diff options
45 files changed, 4840 insertions, 1505 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 5ba415d..5d34ad6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,10 +1,16 @@ cmake_minimum_required(VERSION 2.8) project(Instrument) - +include(FindPkgConfig) set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) find_package(Glib) find_package(GIO) find_package(Mhash) +find_package(PAM) + +pkg_check_modules(LIBUSER REQUIRED libuser) +add_definitions(${LIBUSER_CFLAGS}) +#add_definitions(${PAM_INCLUDE_DIR}) + include_directories(${GLIB_PKG_INCLUDE_DIRS}) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -funsigned-char -Wall") add_executable(instr-daemon instr-daemon.c @@ -22,12 +28,16 @@ add_executable(instr-daemon instr-daemon.c bus.c monitor.c menus.c - dummy_functions.c gpib.c + dds.c + vxi11_server.c + vxi11_xdr.c + vxi11_svc.c + vxi11_clnt.c ) add_executable(instr-client instr-client.c) -target_link_libraries(instr-daemon gio-2.0 gobject-2.0 glib-2.0 mhash m) +target_link_libraries(instr-daemon gio-2.0 gobject-2.0 glib-2.0 gthread-2.0 mhash m pam user) target_link_libraries(instr-client gio-2.0 gobject-2.0 glib-2.0) INSTALL(TARGETS instr-daemon instr-client diff --git a/build/FindGlib.cmake b/build/FindGlib.cmake deleted file mode 100644 index f1986c9..0000000 --- a/build/FindGlib.cmake +++ /dev/null @@ -1,42 +0,0 @@ -pkg_check_modules(GLIB_PKG glib-2.0) - -if (GLIB_PKG_FOUND) - find_path(GLIB_INCLUDE_DIR NAMES glib.h PATH_SUFFIXES glib-2.0 - PATHS - ${GLIB_PKG_INCLUDE_DIRS} - /usr/include/glib-2.0 - /usr/include - /usr/local/include - ) - find_path(GLIB_CONFIG_INCLUDE_DIR NAMES glibconfig.h PATHS ${GLIB_PKG_LIBDIR} PATH_SUFFIXES glib-2.0/include) - - find_library(GLIB_LIBRARIES NAMES glib-2.0 - PATHS - ${GLIB_PKG_LIBRARY_DIRS} - /usr/lib - /usr/local/lib - ) - -else (GLIB_PKG_FOUND) - # Find Glib even if pkg-config is not working (eg. cross compiling to Windows) - find_library(GLIB_LIBRARIES NAMES glib-2.0) - string (REGEX REPLACE "/[^/]*$" "" GLIB_LIBRARIES_DIR ${GLIB_LIBRARIES}) - - find_path(GLIB_INCLUDE_DIR NAMES glib.h PATH_SUFFIXES glib-2.0) - find_path(GLIB_CONFIG_INCLUDE_DIR NAMES glibconfig.h PATHS ${GLIB_LIBRARIES_DIR} PATH_SUFFIXES glib-2.0/include) - -endif (GLIB_PKG_FOUND) - -if (GLIB_INCLUDE_DIR AND GLIB_CONFIG_INCLUDE_DIR AND GLIB_LIBRARIES) - set(GLIB_INCLUDE_DIRS ${GLIB_INCLUDE_DIR} ${GLIB_CONFIG_INCLUDE_DIR}) -endif (GLIB_INCLUDE_DIR AND GLIB_CONFIG_INCLUDE_DIR AND GLIB_LIBRARIES) - -if(GLIB_INCLUDE_DIRS AND GLIB_LIBRARIES) - set(GLIB_FOUND TRUE CACHE INTERNAL "glib-2.0 found") - message(STATUS "Found glib-2.0: ${GLIB_INCLUDE_DIR}, ${GLIB_LIBRARIES}") -else(GLIB_INCLUDE_DIRS AND GLIB_LIBRARIES) - set(GLIB_FOUND FALSE CACHE INTERNAL "glib-2.0 found") - message(STATUS "glib-2.0 not found.") -endif(GLIB_INCLUDE_DIRS AND GLIB_LIBRARIES) - -mark_as_advanced(GLIB_INCLUDE_DIR GLIB_CONFIG_INCLUDE_DIR GLIB_INCLUDE_DIRS GLIB_LIBRARIES) @@ -15,6 +15,7 @@ #include <unistd.h> #include <stdbool.h> #include <inttypes.h> +#include "globals.h" #include "bus.h" #define GPIO_SYSFSPATH "/sys/class/gpio" @@ -176,10 +177,6 @@ static void gpmc_printinfo() static void gpmc_setup(void) { - int chipselect = 0; - int size = GPMC_SIZE_16MB; - bool enablecs = true; - int baseaddress = 1; int CSWROFFTIME = TOTAL_IO_CYCLE; @@ -201,6 +198,12 @@ static void gpmc_setup(void) int WRACCESSTIME = DATA_READY; int config6 = WRACCESSTIME << 24; + //uart5 stuff + pinmux_configurepin("lcd_data9", BIDIR | PULL_UP | MODE_4); + pinmux_configurepin("lcd_data8", MODE_4); + pinmux_configurepin("lcd_data14", BIDIR | PULL_UP | MODE_6); + pinmux_configurepin("lcd_data15", MODE_6); + // pinmux_configurepin("gpmc_csn0", PULL_UP | MODE_0); pinmux_configurepin("gpmc_oen_ren", PULL_UP | MODE_0); @@ -224,11 +227,15 @@ static void gpmc_setup(void) pinmux_configurepin("lcd_data6", PULL_UP | MODE_1); pinmux_configurepin("lcd_data7", PULL_UP | MODE_1); - int displacement = GPMC_CHIPSELECTCONFIGDISPLACEMENT * chipselect; - gpmc_mapregisters(); if (registers != MAP_FAILED) { + int chipselect = 0; + int size = GPMC_SIZE_16MB; + bool enablecs = true; + int baseaddress = 1; + int displacement = GPMC_CHIPSELECTCONFIGDISPLACEMENT * chipselect; + // disable before playing with the registers.. *(registers + displacement + GPMC_CONFIG7) = 0x0; @@ -252,7 +259,7 @@ static int gpio_export(unsigned gpio_pin) { FILE* exportfile = fopen(GPIO_SYSFSPATH"/"GPIO_EXPORTNODE, "w"); if (exportfile != NULL) { - fprintf(exportfile, "%d\n", gpio_pin); + fprintf(exportfile, "%u\n", gpio_pin); fclose(exportfile); return 0; } @@ -267,7 +274,7 @@ static int gpio_unexport(unsigned gpio_pin) { FILE* unexportfile = fopen(GPIO_SYSFSPATH"/"GPIO_UNEXPORTNODE, "w"); if (unexportfile != NULL) { - fprintf(unexportfile, "%d\n", gpio_pin); + fprintf(unexportfile, "%u\n", gpio_pin); fclose(unexportfile); return 0; } @@ -281,7 +288,7 @@ static int gpio_unexport(unsigned gpio_pin) static int gpio_changedirection(unsigned gpio_pin, bool out) { char path[PATHLEN]; - snprintf(path, PATHLEN, GPIO_SYSFSPATH"/gpio%d/"GPIO_DIRECTIONNODE, gpio_pin); + snprintf(path, PATHLEN, GPIO_SYSFSPATH"/gpio%u/"GPIO_DIRECTIONNODE, gpio_pin); FILE* directionfile = fopen(path, "w"); if (directionfile != NULL) { if (out) { @@ -298,7 +305,7 @@ static int gpio_changedirection(unsigned gpio_pin, bool out) static void gpio_getvaluenodepath(unsigned gpio_pin, char* buffer) { - snprintf(buffer, PATHLEN, GPIO_SYSFSPATH"/gpio%d/"GPIO_VALUENODE, gpio_pin); + snprintf(buffer, PATHLEN, GPIO_SYSFSPATH"/gpio%u/"GPIO_VALUENODE, gpio_pin); } /* @@ -354,18 +361,15 @@ static unsigned gpio_pins[] = { GPIO0_X + 22, // i.e., GPIO0_22 static volatile uint8_t* extbus; -static bool isbb = false; void bus_init() { - isbb = util_isbeaglebone(); + globals.HWDetect.beaglebone = util_isbeaglebone(); - if (!isbb) { + if (!globals.HWDetect.beaglebone) { printf("This doesn't seem to be a beaglebone.. bus stuff disabled!\n"); - } - - if (isbb) { + } else { gpmc_setup(); extbus = (uint8_t*) util_mapmemoryblock(0x01000000, 0x100); @@ -380,9 +384,9 @@ void bus_init() gpio_changedirection(gpio_pins[i], true); } - // FIXME: make this more elegant - // + // this could be more elegant - // the POWER_FAIL pin is an input + gpio_changedirection(gpio_pins[POWER_FAIL], false); } } @@ -390,7 +394,7 @@ void bus_init() int bus_getpin(int pin) { - if (isbb) { + if (globals.HWDetect.beaglebone) { return gpio_readvalue(gpio_pins[pin]); } else { return 0; @@ -399,21 +403,21 @@ int bus_getpin(int pin) void bus_setpin(int pin, int value) { - if (isbb) { + if (globals.HWDetect.beaglebone) { gpio_writevalue(gpio_pins[pin], value & 0x1); } } void bus_writebyte(uint8_t address, uint8_t data) { - if (isbb) { + if (globals.HWDetect.beaglebone) { *(extbus + address) = data; } } uint8_t bus_readbyte(uint8_t address) { - if (isbb) { + if (globals.HWDetect.beaglebone) { return *(extbus + address); } else { return 0; @@ -422,7 +426,7 @@ uint8_t bus_readbyte(uint8_t address) void bus_shutdown() { - if (isbb) { + if (globals.HWDetect.beaglebone) { util_unmapmemoryblock((void*) extbus, 0x100); int i; for (i = 0; i < SIZEOFARRAY(gpio_pins); i++) { diff --git a/cmake/FindPAM.cmake b/cmake/FindPAM.cmake new file mode 100644 index 0000000..1ada899 --- /dev/null +++ b/cmake/FindPAM.cmake @@ -0,0 +1,20 @@ +find_path(PAM_INCLUDE_DIR NAMES security/pam_appl.h security/pam_misc.h) +find_library(PAM_LIBRARY pam) + +if (PAM_INCLUDE_DIR AND PAM_LIBRARY) + set(PAM_FOUND TRUE) +endif (PAM_INCLUDE_DIR AND PAM_LIBRARY) + +if (PAM_INCLUDE_DIR) + message(STATUS "Found PAM includes ${PAM_INCLUDE_DIR}") +else (PAM_INCLUDE_DIR) + message(FATAL_ERROR "PAM includes were not found") +endif (PAM_INCLUDE_DIR) + +if (PAM_LIBRARY) + message(STATUS "Found PAM library ${PAM_LIBRARY}") +else (PAM_LIBRARY) + message(FATAL_ERROR "PAM library was not found") +endif (PAM_LIBRARY) + +mark_as_advanced(PAM_INCLUDE_DIR PAM_LIBRARY) @@ -0,0 +1,89 @@ +#include <stdbool.h> +#include <fcntl.h> +#include <stdio.h> +#include <unistd.h> + +#include "dds.h" + +#define IIODEVICEPATH "/sys/bus/iio/devices/iio:device" +#define DACIIODEVICE "0" +#define DDSIIODEVICE "1" + +#define DDSFREQNODE "dds0_freq0" +#define DDSOUTPUTENABLENODE "dds0_out_enable" +#define DDSSQOUTPUTENABLENODE "dds0_out1_enable" +#define DDSWAVETYPENODE "dds0_out0_wavetype" +#define DDSWAVETYPESINE "sine\n" +#define DDSWAVETYPETRI "triangle\n" + +#define DACSCALENODE "out_voltage_scale" +#define DACOUTPUTNODE "out_voltage0_raw" + +#define ENABLE "1\n" +#define DISABLE "0\n" + +void dds_setamplitude(float millivolts) +{ + int scalefd = open(IIODEVICEPATH""DACIIODEVICE"/"DACSCALENODE, O_RDONLY); + int outputfd = open(IIODEVICEPATH""DACIIODEVICE"/"DACOUTPUTNODE, O_WRONLY); + + if (outputfd < 0 || scalefd < 0) { + printf("Couldn't open one or more of the control nodes for the dac\n"); + } + + // read the scale value and turn it into a float + float scale = 0; + char scalebuff[64]; + + if (read(scalefd, scalebuff, sizeof(scalebuff))) { + sscanf(scalebuff, "%10f\n", &scale); // the string should be ?.??? but round up the width a bit just in case + } + + if (scale == 0) { + printf("couldn't read scale or scale is invalid\n"); + return; + } + + // create a buffer with the scaled millivolt value and write it + char outputbuff[64]; + int outputchars = snprintf(outputbuff, sizeof(outputbuff), "%d\n", (int) (millivolts / scale)); + write(outputfd, outputbuff, outputchars); + + close(scalefd); + close(outputfd); +} + +void dds_setupwave(int frequency, bool squarewaveoutput, bool triangle) +{ + int wavetypefd = open(IIODEVICEPATH""DDSIIODEVICE"/"DDSWAVETYPENODE, O_WRONLY); + int outputenablefd = open(IIODEVICEPATH""DDSIIODEVICE"/"DDSOUTPUTENABLENODE, O_WRONLY); + int sqwaveenablefd = open(IIODEVICEPATH""DDSIIODEVICE"/"DDSSQOUTPUTENABLENODE, O_WRONLY); + int freqfd = open(IIODEVICEPATH""DDSIIODEVICE"/"DDSFREQNODE, O_WRONLY); + + if (wavetypefd < 0 || outputenablefd < 0 || sqwaveenablefd < 0 || freqfd < 0) { + printf("Couldn't open one or more of the control nodes for the dds\n"); + return; + } + + if (triangle) { + // squarewave output on the signbit out pin can't be selected at the same time as triangle wave + write(sqwaveenablefd, DISABLE, sizeof(DISABLE)); + write(wavetypefd, DDSWAVETYPETRI, sizeof(DDSWAVETYPETRI)); + } else { + // enable/disable the square wave ouput and reset the wavetype + write(sqwaveenablefd, squarewaveoutput ? ENABLE : DISABLE, squarewaveoutput ? sizeof(ENABLE) : sizeof(DISABLE)); + write(wavetypefd, DDSWAVETYPESINE, sizeof(DDSWAVETYPESINE)); + } + + // generate a buffer with the frequency and set it + char freqbuff[64]; + int freqchars = snprintf(freqbuff, sizeof(freqbuff), "%d\n", frequency); + write(freqfd, freqbuff, freqchars); + + write(outputenablefd, ENABLE, sizeof(ENABLE)); + + close(sqwaveenablefd); + close(wavetypefd); + close(freqfd); + close(outputenablefd); +} @@ -0,0 +1,3 @@ +#include <stdbool.h> +void dds_setamplitude(float millivolts); +void dds_setupwave(int frequency, bool squarewaveoutput, bool triangle); diff --git a/device-functions.c b/device-functions.c index 0e5338a..f3c06d3 100644 --- a/device-functions.c +++ b/device-functions.c @@ -1,5 +1,4 @@ #include "device-functions.h" -#include "dummy_functions.h" #include "globals.h" #include "version.h" #include "error_utils.h" @@ -10,11 +9,19 @@ #include "menus.h" #include <math.h> #include <glib.h> +#include <libuser/user.h> +#include <libuser/config.h> +#include <security/pam_appl.h> +#include <security/pam_misc.h> + + +static void start_gate_override (); +static void stop_gate_override (); void idn_string(gchar** response) { - *response = g_strdup_printf ("AVTECH ELECTROSYSTEMS,%s,%s,v%s", + *response = g_strdup_printf ("AVTECH ELECTROSYSTEMS,%s,SN:%s,v%s", globals.Flash.model_num, globals.Flash.serial_num, FW_VERSION); @@ -118,7 +125,6 @@ void Main_Rst (void) // establishes min/max values for queries, but reports no errors Error_check(globals.ChannelState); - globals.Changes.update_whole_main_menu=YES; Ctrl_PRF_Limiter(1); @@ -132,7 +138,7 @@ void Main_Rst (void) } -int set_dac(int dac, int word) +void set_dac(int dac, int word) { /* allows dacs to be disabled (using dac=-1, for example) */ if ((dac >= 0) && (dac < 8)) { @@ -389,6 +395,10 @@ int Set_Pw(int check_possible_only,int word_override,int range_override,int chan /* AVPP-style: lower PW range is voltage-controlled */ if (globals.Flash.volt_ctrl_pw[channel]) { + + // reset PG B line (see below) + globals.Registers.shift_reg_out[2] &= (long)0x7ffff; + /* use DAC8420 to control PW in lowest PW range */ if (!relay_range) { set_dac(globals.Flash.pw_dac[channel],word_out); @@ -407,6 +417,9 @@ int Set_Pw(int check_possible_only,int word_override,int range_override,int chan if (relay_range==1) { cap_range_control=0; + // set XTRA RLY 5 high in this range for AVR-E3-B-R5-N-M5, and other + // units with PG A, B, and C. This corresponds to PG B. + globals.Registers.shift_reg_out[2] |= (long)0x80000; } else { cap_range_control = 1 << (relay_range-2); } @@ -444,10 +457,6 @@ int Set_Pw(int check_possible_only,int word_override,int range_override,int chan set_dac(globals.Flash.monocycle_dac[0],word_out); } - if (set_pw!=globals.ChannelState[channel].pw) { - globals.Changes.update_pw=YES; - } - globals.ChannelState[channel].pw=set_pw; Set_Update_Chans(); @@ -628,10 +637,6 @@ int Set_frequency(int check_possible_only,int word_override,int range_override,i globals.Registers.shift_reg_out[2] = ((long)(globals.Registers.shift_reg_out[2] & 0xfff00)) | ((long)cap_range_control); /* bottom 8 bits of 20 bits */ } - if (set_freq!=globals.ChannelState[channel].frequency) { - globals.Changes.update_freq=YES; - } - g_print_debug("freq range %d, word %d\n",relay_range,word_out); globals.ChannelState[channel].frequency=set_freq; @@ -726,10 +731,6 @@ int Set_Delay(int check_possible_only,int word_override,int range_override,int c control_pcb107(Second_Dly_Port,globals.Flash.delay_dac[channel],word_out,relay_range); } - if (set_delay!=globals.ChannelState[channel].delay) { - globals.Changes.update_delay=YES; - } - globals.ChannelState[channel].delay=set_delay; Set_Update_Chans(); @@ -756,13 +757,11 @@ int Set_Double(int channel,int new_setting) } if (new_setting == double_off) { - globals.Registers.shift_reg_out[0] &= 0xdf; /* turn double-pulse off */ + globals.Registers.shift_reg_out[0] &= 0xdf; // turn double-pulse off + Ctrl_PRF_Limiter (1); // normal prf limiting } else { - globals.Registers.shift_reg_out[0] |= 0x20; /* turn double-pulse on */ - } - - if (globals.ChannelState[channel].double_pulse!=new_setting) { - globals.Changes.update_delay=YES; + globals.Registers.shift_reg_out[0] |= 0x20; // turn double-pulse on + Ctrl_PRF_Limiter (0); // disable prf limiter } globals.ChannelState[channel].double_pulse=new_setting; @@ -786,7 +785,7 @@ void Ctrl_PRF_Limiter(int enable) } -int Set_Mux(int channel) +void Set_Mux(int channel) { int mux_out; @@ -849,8 +848,6 @@ int Set_Func(int channel,int mode) globals.Registers.shift_reg_out[2] = ((long) (globals.Registers.shift_reg_out[2] & 0xbffff)) | (long) (((long) (mode & 0x08)) << (globals.Flash.ext_amplify_xtra_rly[channel]+11)); - - globals.Changes.update_func=YES; } @@ -892,10 +889,6 @@ int Set_Pol(int channel,int mode) return error_num; } - if (globals.ChannelState[channel].polarity!=mode) { - globals.Changes.update_inv=YES; - } - globals.ChannelState[channel].polarity=mode; Set_Mux(channel); @@ -912,10 +905,6 @@ int Set_Hold(int channel,int mode) return InvalidChannel; } - if (globals.ChannelState[channel].hold_setting!=mode) { - globals.Changes.update_pw=YES; - } - globals.ChannelState[channel].hold_setting=mode; Set_Update_Chans(); @@ -956,6 +945,9 @@ int Set_Output_State(int channel,int mode) bus_setpin(OUTPUT_RELAY, 1); /* turn output on */ bus_setpin(PW_ENABLE, 1); /* enable PW circuit */ + + g_usleep (800e3); /* wait for extended-off circuit to work */ + globals.Timers.last_activity_at[channel] = sec_timer(); } else { bus_setpin(PW_ENABLE, 0); /* disable PW circuit */ @@ -963,10 +955,6 @@ int Set_Output_State(int channel,int mode) globals.Timers.last_activity_at[channel] = 0L; } - if (globals.ChannelState[channel].output_state!=mode) { - globals.Changes.update_output=YES; - } - globals.ChannelState[channel].output_state=mode; Set_Update_Chans(); @@ -1018,8 +1006,6 @@ int Set_Trig_Source(int channel,int mode) Set_frequency(0,0,0,channel,use_freq); Set_Pwmode(channel,use_ab_mode); } - - globals.Changes.update_freq=YES; } globals.ChannelState[channel].trigger_source=mode; @@ -1031,34 +1017,23 @@ int Set_Trig_Source(int channel,int mode) mode=source_external; } - + gate_mode = 0; if (mode==source_internal) { - gate_mode=0; /* frequency is automatically lowered if pw or delay have been changed to conflicting */ /* settings while in a non-internal mode */ globals.Registers.shift_reg_out[0] = (globals.Registers.shift_reg_out[0] & 0xe3) | 0; } else if (mode==source_external) { - gate_mode=0; globals.ChannelState[channel].hold_setting=hold_width; globals.Registers.shift_reg_out[0] = (globals.Registers.shift_reg_out[0] & 0xe3) | 3<<2; } else if (mode==source_manual) { - gate_mode=0; globals.ChannelState[channel].hold_setting=hold_width; globals.Registers.shift_reg_out[0] = (globals.Registers.shift_reg_out[0] & 0xe3) | 1<<2; } else if (mode==source_hold) { gate_mode=1; } else if (mode==source_immediate) { - if (gate_mode==1) { - globals.Registers.shift_reg_out[0] = (globals.Registers.shift_reg_out[0] & 0xe3) | 4<<2; - Main_update_shift_registers(); - gate_mode=0; /* allow triggering */ - bus_setpin(O_GATE, gate_mode); - globals.Registers.shift_reg_out[0] = (globals.Registers.shift_reg_out[0] & 0xe3) | 7<<2; - } else { - globals.Registers.shift_reg_out[0] = (globals.Registers.shift_reg_out[0] & 0xe3) | 4<<2; - Main_update_shift_registers(); - globals.Registers.shift_reg_out[0] = (globals.Registers.shift_reg_out[0] & 0xe3) | 7<<2; - } + globals.Registers.shift_reg_out[0] = (globals.Registers.shift_reg_out[0] & 0xe3) | 4<<2; + Main_update_shift_registers(); + globals.Registers.shift_reg_out[0] = (globals.Registers.shift_reg_out[0] & 0xe3) | 7<<2; } Main_update_shift_registers(); @@ -1081,10 +1056,6 @@ int Set_Gate_Sync(int channel,int mode) globals.Registers.shift_reg_out[0] = (globals.Registers.shift_reg_out[0] & 0xfe) | 1; } - if (globals.ChannelState[channel].gate_type!=mode) { - globals.Changes.update_gate=YES; - } - globals.ChannelState[channel].gate_type=mode; Set_Update_Chans(); @@ -1105,10 +1076,6 @@ int Set_Gate_Level(int channel,int mode) globals.Registers.shift_reg_out[0] = (globals.Registers.shift_reg_out[0] & 0xfd) | 0; } - if (globals.ChannelState[channel].gate_level!=mode) { - globals.Changes.update_gate=YES; - } - globals.ChannelState[channel].gate_level=mode; Set_Update_Chans(); @@ -1116,7 +1083,7 @@ int Set_Gate_Level(int channel,int mode) } -int start_gate_override () +static void start_gate_override () { /* just set gate bit high, if not already high */ int i; @@ -1127,7 +1094,7 @@ int start_gate_override () } -int stop_gate_override () +static void stop_gate_override () { /* release gate (if not in hold mode) */ int i; @@ -1351,10 +1318,6 @@ int Set_Pwmode(int channel,int mode) return AB_Mode_Error; } - if (globals.ChannelState[channel].ab_mode!=mode) { - globals.Changes.update_pw=YES; - } - globals.ChannelState[channel].ab_mode=mode; Set_Mux(0); @@ -1566,11 +1529,6 @@ int Set_Logic_Level(int channel,int mode) } } - - if (globals.ChannelState[channel].logic_level!=mode) { - globals.Changes.update_logic_level=YES; - } - globals.ChannelState[channel].logic_level=mode; Set_Update_Chans(); @@ -1689,7 +1647,6 @@ int Set_Route(int channel, int module, int mode) } if (mode!=globals.ChannelState[channel].route_primary) { - globals.Changes.update_routes=YES; globals.ChannelState[channel].route_primary=mode; } } @@ -1701,7 +1658,6 @@ int Set_Route(int channel, int module, int mode) } if (mode!=globals.ChannelState[channel].route_secondary) { - globals.Changes.update_routes=YES; globals.ChannelState[channel].route_secondary=mode; } } @@ -1796,7 +1752,7 @@ int Set_Dly_Shr_Nom(int channel,int calibration_point_number) Main_update_shift_registers(); - Menu_Update_Display(); + Show_Main_Menu(); return OK; } @@ -2055,7 +2011,7 @@ int Set_Cal_Nom(int channel,int calibration_point_number,int parameter, float *n Set_Mux(true_channel); Main_update_shift_registers(); - Menu_Update_Display(); + Show_Main_Menu(); /* re-enable error-checking */ globals.Flash.fully_programmed=All_Programmed; @@ -2234,7 +2190,7 @@ int Set_VI_Cal_Pnt(int parameter,int channel,int calibration_point_number,float Set_Cal_Nom(channel,calibration_point_number,parameter,NULL); Main_update_shift_registers(); - Menu_Update_Display(); + Show_Main_Menu(); eprom_loc = (char *) (&pwl_amp[index]) - (char *) &(globals.Flash.flash_start); writeUserBlock(&globals.Flash, eprom_loc, sizeof(nom_ampl)); @@ -2397,7 +2353,7 @@ int Set_VI_Del_Cal(int parameter,int channel,int calibration_point_number) Set_Offset(0,0,0,0,channel,0.0); Main_update_shift_registers(); - Menu_Update_Display(); + Show_Main_Menu(); eprom_loc = (char *) pointer_short1 - (char *) &(globals.Flash.flash_start); writeUserBlock(&globals.Flash, eprom_loc, size_of_short1); @@ -2500,6 +2456,32 @@ int Set_VI_Control(int parameter,int channel,float new_ampl,int *point_found,int top_range_only=1; } + if (globals.Flash.couple_first_N_pw_ranges_to_ampl_ranges[channel]) { + int curr_pw_range = 0; + int parse_sr = globals.Registers.shift_reg_out[3] & 0x7f; + + while (parse_sr) { + ++curr_pw_range; + parse_sr = parse_sr >> 1; + } + + if (globals.Flash.volt_ctrl_pw[channel]) { + // ranges are shifted in these units + ++curr_pw_range; + // except for minimum range + if (globals.Registers.shift_reg_out[3] & (long)0x01000) { + curr_pw_range = 0; + } + } + + starting_range = curr_pw_range; + if (starting_range > globals.Flash.couple_first_N_pw_ranges_to_ampl_ranges[channel]) { + starting_range = globals.Flash.couple_first_N_pw_ranges_to_ampl_ranges[channel]; + } + + top_range_only = 0; + } + break; case pwl_os_values: decreasing_values_allowed=YES; /* allows Vc=0 to corresponds to most + OS, and Vc=10V to give most - OS */ @@ -3366,11 +3348,6 @@ int Set_Burst_Count(int channel,int count,float new_burst_time) return check_valid; } - /* update variables if OK */ - if (count!=globals.ChannelState[channel].burst_count) { - globals.Changes.update_burst_count=YES; - } - globals.ChannelState[channel].burst_count = count; Set_Update_Chans(); @@ -3496,11 +3473,6 @@ int Set_Burst_Time(int check_possible_only,int word_override,int range_override, globals.Registers.last_relay_driver_settings[2] = relay_range; - /* update variables if OK */ - if (new_burst_time!=globals.ChannelState[channel].burst_time) { - globals.Changes.update_burst_time=YES; - } - globals.ChannelState[channel].burst_time = new_burst_time; Set_Update_Chans(); @@ -3631,11 +3603,6 @@ int Set_rise_time(int check_possible_only,int word_override,int range_override,i } } - /* update variables if OK */ - if (new_rise_time!=globals.ChannelState[channel].rise_time) { - globals.Changes.update_rise_time=YES; - } - globals.ChannelState[channel].rise_time = new_rise_time; globals.Registers.last_rise_time_relay_setting = range_control; @@ -3683,11 +3650,6 @@ int Set_current_limit(int check_possible_only,int channel,float new_adj_current_ word_out = (int) ( ((float) dac_max) * (limit/globals.Flash.current_limit_full_scale[channel]) ); set_dac(globals.Flash.current_limit_dac[channel],word_out); - /* update variables if OK */ - if (limit!=globals.ChannelState[channel].soft_current_limit) { - globals.Changes.update_soft_current_limit=YES; - } - globals.ChannelState[channel].soft_current_limit=limit; return OK; @@ -3837,11 +3799,6 @@ int Set_slew(int check_possible_only,int word_override,int range_override,int ch I2C_Write(PCF8574,range_control); - /* update variables if OK */ - if (new_slew!=globals.ChannelState[channel].slew) { - globals.Changes.update_slew=YES; - } - globals.ChannelState[channel].slew = new_slew; Set_Update_Chans(); @@ -4023,8 +3980,9 @@ int go_cal(CalStruct *caldata) int i, status, points; float meas, nom_val, change; float min_val, max_val, chk_val; - char lcd_msg[LCD_cols+1]; - char prefix[LCD_cols+1]; + + gchar *lcd_msg = NULL; + gchar *prefix = NULL; points = Get_VI_Num_Pnts(caldata->cal_type,caldata->channel); @@ -4059,14 +4017,16 @@ int go_cal(CalStruct *caldata) LCD_write(0,0,"Self-calibration in progress."); if (caldata->cal_type == pwl_period_values) { - sprintf (prefix, "CH%d PER %d:",caldata->channel+1,i); + prefix = g_strdup_printf ("CH%d PER %d:",caldata->channel+1,i); } else if (caldata->cal_type == pwl_pw_values) { - sprintf (prefix, "CH%d PW %d:",caldata->channel+1,i); + prefix = g_strdup_printf ("CH%d PW %d:",caldata->channel+1,i); } else if (caldata->cal_type == pwl_delay_values) { - sprintf (prefix, "CH%d DLY %d:",caldata->channel+1,i); + prefix = g_strdup_printf ("CH%d DLY %d:",caldata->channel+1,i); } - sprintf (lcd_msg, "%s %.3e",prefix,nom_val); + + lcd_msg = g_strdup_printf ("%s %.3e",prefix,nom_val); LCD_write(2,0,lcd_msg); + g_free (lcd_msg); if (caldata->cal_type == pwl_period_values) { I2C_Self_Cal (caldata->channel, MEAS_PRF, &meas, 1.0 / globals.ChannelState[caldata->channel].frequency); @@ -4090,10 +4050,17 @@ int go_cal(CalStruct *caldata) LCD_clear(); LCD_write(0,0,"Self-calibration in progress."); - sprintf (lcd_msg, "%s %.3e -> %.3e",prefix,nom_val,meas); + + lcd_msg = g_strdup_printf ("%s %.3e -> %.3e",prefix,nom_val,meas); LCD_write(2,0,lcd_msg); - sprintf (lcd_msg, "changed %6.2f%%, err: %d",change,status); + g_free (lcd_msg); + + lcd_msg = g_strdup_printf ("changed %6.2f%%, err: %d",change,status); LCD_write(3,0,lcd_msg); + g_free (lcd_msg); + + g_free (prefix); + g_usleep (2e6); } } @@ -4102,44 +4069,52 @@ int go_cal(CalStruct *caldata) } -int cal_string(char *parameter, CalStruct *caldata) +void cal_string(char *parameter, CalStruct *caldata) { - char string[max_output_length]; - - sprintf(string,"CH%d %s cal: %d errors. Adj: %6.2f%% max, %6.2f%% avg.\n\r", caldata->channel+1,parameter, caldata->error, caldata->max_change, caldata->avg_change); - strcat (caldata->response, string); + gchar *string = g_strdup_printf ("CH%d %s cal: %d errors. Adj: %6.2f%% max, %6.2f%% avg.\r\n", caldata->channel+1,parameter, caldata->error, caldata->max_change, caldata->avg_change); + g_string_append (caldata->response, string); + g_free (string); } int self_cal() { CalStruct caldata; - return do_full_self_cal(&caldata); + + int status = do_full_self_cal(&caldata); + + g_string_free (caldata.response, TRUE); + + return status; } int do_full_self_cal(CalStruct *caldata) { - char string[LCD_cols+1]; + gchar *string; long start_timer, diff_timer; int eprom_loc; + caldata->response = g_string_new (""); + Menu_Clear_Buttons(); LCD_clear(); /*0123456789012345678901234567890123456789*/ LCD_write(0,0,"Self-calibration in progress."); /*0123456789012345678901234567890123456789*/ - sprintf(string,"Typical run time: %d min, %d sec.", globals.Flash.self_cal_typical_time_min, globals.Flash.self_cal_typical_time_sec); + + string = g_strdup_printf ("Typical run time: %d min, %d sec.", globals.Flash.self_cal_typical_time_min, globals.Flash.self_cal_typical_time_sec); LCD_write(1,0,string); + g_free (string); while ((sec_timer() - globals.Timers.startup_timer_value) < (long)globals.Flash.self_cal_pause) { /*0123456789012345678901234567890123456789*/ - sprintf (string, "Min warm-up is %ds, on for %lds.", globals.Flash.self_cal_pause, sec_timer() - globals.Timers.startup_timer_value); + string = g_strdup_printf ("Min warm-up is %ds, on for %lds.", globals.Flash.self_cal_pause, sec_timer() - globals.Timers.startup_timer_value); LCD_write(3,0,string); + g_free (string); g_usleep (2e5); } start_timer = sec_timer(); - caldata->response[0] = 0; caldata->total_errors = 0; caldata->total_max_change = 0.0; @@ -4177,21 +4152,24 @@ int do_full_self_cal(CalStruct *caldata) LCD_clear(); /*0123456789012345678901234567890123456789*/ LCD_write(0,0,"Self-calibration complete."); - sprintf (string, "%d errors. Max change: %6.2f%%", caldata->total_errors, caldata->total_max_change); + + string = g_strdup_printf ("%d errors. Max change: %6.2f%%", caldata->total_errors, caldata->total_max_change); LCD_write(1,0,string); + g_free (string); + LCD_write(2,0,"More details are provided by \"cal?\""); g_usleep (3e6); - Menu_Update_Display(); + Show_Main_Menu(); diff_timer = sec_timer() - start_timer; globals.Flash.self_cal_typical_time_min = (int) (diff_timer / 60); globals.Flash.self_cal_typical_time_sec = (int) (diff_timer % 60); - // FIXME - cpp buffer error - sprintf(string,"Completed in %d minutes and %d seconds\n\r", globals.Flash.self_cal_typical_time_min, globals.Flash.self_cal_typical_time_sec); - strcat (caldata->response, string); + string = g_strdup_printf ("Completed in %d minutes and %d seconds\r\n", globals.Flash.self_cal_typical_time_min, globals.Flash.self_cal_typical_time_sec); + g_string_append (caldata->response, string); + g_free (string); eprom_loc = (char *) &(globals.Flash.self_cal_typical_time_min) - (char *) &(globals.Flash.flash_start); writeUserBlock(&globals.Flash, eprom_loc, sizeof(globals.Flash.self_cal_typical_time_min)); @@ -4200,9 +4178,12 @@ int do_full_self_cal(CalStruct *caldata) if (caldata->total_errors) { return SelfCalError; + } else { + return OK; } } + int I2C_Self_Cal(int channel, int meas_mode, float *meas, float target_time) { #define MAX_TRIES 35 @@ -4451,7 +4432,6 @@ void Set_Rcl(int setting_num) Menu_Clear_Buttons(); globals.Flags.do_check_settings=YES; /* check for conflicting settings */ - globals.Changes.update_whole_main_menu=YES; Error_check(globals.ChannelState); /* establishes min/max values for queries, but reports no errors */ @@ -4538,6 +4518,9 @@ void Set_Sav(int setting_num) void Main_update_shift_registers() { + static GStaticMutex mutex = G_STATIC_MUTEX_INIT; + g_static_mutex_lock (&mutex); + /* send MSB first, LSB last */ /* send highest # SR first */ @@ -4619,40 +4602,131 @@ void Main_update_shift_registers() /* save relay data for comparision next time */ globals.Registers.last_relay_driver_settings[0]=globals.Registers.shift_reg_out[2]; globals.Registers.last_relay_driver_settings[1]=globals.Registers.shift_reg_out[3]; + + // reset update sensors + globals.Changes.update_os = 0; + globals.Changes.update_amp = 0; + globals.Changes.update_zout = 0; + globals.Changes.update_load = 0; + + g_static_mutex_unlock (&mutex); +} + + +int IO_Setup_RS232(int baud, char hardhand, gboolean update_flash) +{ + FILE* configfile = fopen("/tmp/instgettyopts", "w"); + if(configfile) { + fprintf(configfile, "OPTS=-L %s\n", hardhand ? "-h" : ""); + fprintf(configfile, "BAUD=%d\n", baud); + fclose(configfile); + system("systemctl --no-block restart inst-getty@ttyO5.service"); + } + + globals.Flash.baud = baud; + globals.Flash.hardhand = hardhand; + + if (update_flash) { + int size = sizeof(globals.Flash.baud) + sizeof(globals.Flash.parity) + sizeof(globals.Flash.stopbits) + + sizeof(globals.Flash.databits) + sizeof(globals.Flash.hardhand) + sizeof(globals.Flash.echo); + + int eprom_loc = (char *) &(globals.Flash.baud) - (char *) &(globals.Flash.flash_start); + writeUserBlock(&globals.Flash, eprom_loc, size); + } + return OK; +} + +// this is a conversation handler for pam, it basically sends the password when pam asks for it + +static int conversation(int num_msg, const struct pam_message **msgs, struct pam_response **resp, void *appdata_ptr) +{ + + struct pam_response* responses = calloc(num_msg, sizeof(struct pam_response)); + if (!responses) { + return PAM_CONV_ERR; + } + + int i; // not compiling in gnu99 mode? + for (i = 0; i < num_msg; i++) { + const struct pam_message *msg = msgs[i]; + struct pam_response* response = &(responses[i]); + switch (msg->msg_style) { + case PAM_PROMPT_ECHO_OFF: + response->resp = strdup((char*) appdata_ptr); + if (!response->resp) { + return PAM_CONV_ERR; + } + break; + + default: + return PAM_CONV_ERR; + } + response->resp_retcode = 0; + } + + *resp = responses; + + return PAM_SUCCESS; } +static gboolean checkpassword(const char* username, char* password) +{ + struct pam_conv pam_conversation = { conversation, password }; + pam_handle_t* pamh; + + if (pam_start("passwd", username, &pam_conversation, &pamh) != PAM_SUCCESS) { + return FALSE; + } + + if (pam_authenticate(pamh, 0) != PAM_SUCCESS) { + return FALSE; + } + + // we only want to check the password and not actually start a session, so get out of here + + pam_end(pamh, 0); + + return TRUE; +} -int IO_Setup_RS232(int baud, char parity, char stopbits, char databits, char hardhand, char echo, gboolean update_flash) +int change_password(gchar *old_password, gchar *new_password) { - // debugging - printf ("baud: %d, parity %d, stop bits %d, data bits %d, handshaking %d, echo %d\n\r", - baud, - parity, // 0 = none, 1 = odd, 2 = even - stopbits, - databits, - hardhand, // 0 = none, 1 = hard - echo); - - // FIXME implement serial port changes here - - if (1) { // FIXME if changes are successful - globals.Flash.baud = baud; - globals.Flash.parity = parity; - globals.Flash.stopbits = stopbits; - globals.Flash.databits = databits; - globals.Flash.hardhand = hardhand; - globals.Flash.echo = echo; - - if (update_flash) { - int size = sizeof(globals.Flash.baud) + sizeof(globals.Flash.parity) + sizeof(globals.Flash.stopbits) + - sizeof(globals.Flash.databits) + sizeof(globals.Flash.hardhand) + sizeof(globals.Flash.echo); - - int eprom_loc = (char *) &(globals.Flash.baud) - (char *) &(globals.Flash.flash_start); - writeUserBlock(&globals.Flash, eprom_loc, size); + + gboolean old_valid = TRUE; + + char* user = "admin"; + + // Skip password check if the supplied old_password is NULL. This + // only happens when resetting the password to the default. + if (old_password != NULL ) { + old_valid = checkpassword(user,old_password); + } + + if (old_valid == TRUE) { + struct lu_context *ctx; + struct lu_error *error = NULL; + struct lu_ent *ent; + + ctx = lu_start(user, lu_user, NULL, NULL, lu_prompt_console_quiet, NULL, &error); + + if (ctx == NULL ) { + return password_change_error; + } + + ent = lu_ent_new(); + + if (lu_user_lookup_name(ctx, user, ent, &error) == FALSE) { + return password_change_error; // user doesn't exist + } + + if (lu_user_setpass(ctx, ent, new_password, FALSE, &error) == FALSE) { + return password_change_error; } + + lu_end(ctx); + return OK; } else { - return HardwareError; + return password_change_error; } } - diff --git a/device-functions.h b/device-functions.h index de4f1b8..dc14abd 100644 --- a/device-functions.h +++ b/device-functions.h @@ -10,7 +10,7 @@ void idn_string(gchar** response); int Set_frequency(int check_possible_only,int word_override,int range_override,int channel,float set_freq); void Main_Rst(void); -int set_dac(int dac, int word); +void set_dac(int dac, int word); int Set_Amplitude(int check_possible_only,int pol_override,int override_on,int word_override,int range_override, int switch_range_only,int channel,float new_ampl,int called_from_set_pw); int Set_Pw(int check_possible_only,int word_override,int range_override,int channel,float set_pw,int called_from_set_ampl); @@ -18,7 +18,7 @@ int Set_Offset(int check_possible_only,int override_on,int word_override,int ran int Set_Delay(int check_possible_only,int word_override,int range_override,int channel,float set_delay); int Set_Double(int channel,int new_setting); void Ctrl_PRF_Limiter(int enable); -int Set_Mux(int channel); +void Set_Mux(int channel); int Set_Func(int channel,int mode); int Set_Pol(int channel,int mode); int Set_Hold(int channel,int mode); @@ -61,7 +61,7 @@ int Set_avrq_res(int check_possible_only,int word_override,int range_override,in int Set_slew(int check_possible_only,int word_override,int range_override,int channel,float new_burst_time); int Set_avrq_ampl(int check_possible_only,int word_override,int range_override,int channel,float new_avrq_ampl); int go_cal(CalStruct *caldata); -int cal_string(char *parameter, CalStruct *caldata); +void cal_string(char *parameter, CalStruct *caldata); int self_cal(); int do_full_self_cal(CalStruct *caldata); int I2C_Self_Cal(int channel, int meas_mode, float *meas, float target_time); @@ -71,6 +71,8 @@ void Set_Sav(int setting_num); void Main_update_shift_registers(); -int IO_Setup_RS232(int baud, char parity, char stopbits, char databits, char handshake, char echo, gboolean update_flash); +int IO_Setup_RS232(int baud, char handshake, gboolean update_flash); + +int change_password (gchar *old_password, gchar *new_password); #endif diff --git a/dummy_functions.c b/dummy_functions.c deleted file mode 100644 index 71d6b59..0000000 --- a/dummy_functions.c +++ /dev/null @@ -1,5 +0,0 @@ -#include "dummy_functions.h" -#include "globals.h" - -void Main_return_to_local() {} - diff --git a/dummy_functions.h b/dummy_functions.h deleted file mode 100644 index 5f9ba2e..0000000 --- a/dummy_functions.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef DUMMY_FUNCTIONS_H_ -#define DUMMY_FUNCTIONS_H_ - -#include "globals.h" - -void Main_return_to_local(); - -#endif - diff --git a/error_utils.c b/error_utils.c index 8681808..974da44 100644 --- a/error_utils.c +++ b/error_utils.c @@ -16,7 +16,6 @@ END DESCRIPTION **********************************************************/ #include <glib.h> #include <math.h> #include "globals.h" -#include "dummy_functions.h" #include "lcd.h" #include "error_utils.h" #include "menus.h" @@ -61,6 +60,7 @@ void set_gpib_error_flags (int error_num) case Soft_Limit_Exceeded: case SelfCalError: case NetworkNotFound: + case Startup_Not_Finished: GPIB_Set_Device_Dependent_Error(); break; default: @@ -116,7 +116,7 @@ void queue_error_from_parser(gchar** response, int error_num) } queue_error_and_get_text(response, error_num); - Menu_Refresh(); + Show_Main_Menu(); return; } @@ -144,8 +144,9 @@ void queue_error_and_display_on_LCD(int error_num) g_free (response); } +extern void send_message(gchar* message); -void queue_and_broadcast_sensor_alarm(int error_num) // FIXME - implement +void queue_and_broadcast_sensor_alarm(int error_num) { if (error_num == OK) { return; @@ -154,6 +155,11 @@ void queue_and_broadcast_sensor_alarm(int error_num) // FIXME - implement gchar* response = NULL; queue_error_and_get_text(&response, error_num); LCD_display_extended_message (response, TRUE, TRUE); + + gchar *broadcast_str = g_strdup_printf ("%s\r\n> ", response); + send_message(broadcast_str); + g_free (broadcast_str); + g_free (response); } @@ -514,6 +520,10 @@ void get_error_text(gchar **response, int error_num) format_error_text(response,-200,"Invalid execution path. Programming error."); break; + case Startup_Not_Finished: + format_error_text(response,-300,"Not ready for commands yet. Still booting up."); + break; + default: format_error_text(response,-200,"Specific problem unknown."); } @@ -523,13 +533,16 @@ void get_error_text(gchar **response, int error_num) int Error_check(ChannelStruct ChannelStateToTest[max_channels]) { + static GStaticMutex mutex = G_STATIC_MUTEX_INIT; + g_static_mutex_lock (&mutex); float max_duty_high_ampl,max_duty_low_ampl,max_duty_this_ampl; float ampl_fixed_max_duty; float temp; float duty_scale; float duty_cycle; - int report_error; + int report_error = OK; + gboolean early_quit = FALSE; int i; int num_of_chan; @@ -635,29 +648,33 @@ int Error_check(ChannelStruct ChannelStateToTest[max_channels]) } - report_error=OK; - - for (i=0; i<num_of_chan; ++i) { + for (i=0; (i<num_of_chan) && !early_quit; ++i) { /* Must be changing a setting */ globals.Timers.last_activity_at[i] = sec_timer (); /* ignore errors if it is in programming mode */ if (globals.Flash.fully_programmed != All_Programmed) { - return OK; + early_quit = TRUE; + break; } if (globals.Flags.do_check_settings==NO) { - return OK; + early_quit = TRUE; + break; } /* check for settings that would cause divide-by-zero errors in the error-checking routine */ if (ChannelStateToTest[i].frequency<smallest_allowed_number) { - return freq_lower_limit; + early_quit = TRUE; + report_error = freq_lower_limit; + break; } if (ChannelStateToTest[i].pw<smallest_allowed_number && globals.Flash.min_pw[i]>0.0) { - return pw_lower_limit; + early_quit = TRUE; + report_error = pw_lower_limit; + break; } /* calculate maximum duty cycle based on amplitude and load, for later use */ @@ -1416,6 +1433,8 @@ int Error_check(ChannelStruct ChannelStateToTest[max_channels]) /* --- done all per-channel checking ---- */ } + g_static_mutex_unlock (&mutex); + return report_error; } @@ -272,10 +272,10 @@ static int readUserBlock(FlashStruct *mem) // hopefully we can use the backup.. if (persistence_unfreeze(BACKUPFILE, mem, sizeof(*mem), 0)) { // if the backup was good overwrite the main file - if (!globals.Flags.shutdown_started) { - globals.Flags.flash_write_in_progress = TRUE; + if (!globals.Sys.shutdown_started) { + globals.Sys.flash_write_in_progress = TRUE; persistence_copyfile(BACKUPFILE, MAINFILE); - globals.Flags.flash_write_in_progress = FALSE; + globals.Sys.flash_write_in_progress = FALSE; } return sizeof(*mem); } @@ -295,21 +295,20 @@ void writeUserBlock(FlashStruct *mem, int addr, int numbytes) // *** that the main file is valid before backing it up I guess... *** // *** but I don't think this situation should arise. *** - static GMutex mutex; - - g_mutex_lock (&mutex); + static GStaticMutex mutex = G_STATIC_MUTEX_INIT; + g_static_mutex_lock (&mutex); if (!globals.Flags.flash_writes_suspended) { // backup the main copy of the file - if (!globals.Flags.shutdown_started) { + if (!globals.Sys.shutdown_started) { - globals.Flags.flash_write_in_progress = TRUE; + globals.Sys.flash_write_in_progress = TRUE; bool backup_ok = persistence_copyfile(MAINFILE, BACKUPFILE); - globals.Flags.flash_write_in_progress = FALSE; + globals.Sys.flash_write_in_progress = FALSE; - if (backup_ok && !globals.Flags.shutdown_started) { - globals.Flags.flash_write_in_progress = TRUE; + if (backup_ok && !globals.Sys.shutdown_started) { + globals.Sys.flash_write_in_progress = TRUE; if (!persistence_freeze(MAINFILE, mem, addr, numbytes, sizeof(*mem), 0)) { if (errno != PERSIST_ERR_COULDNTWRITE) { @@ -318,14 +317,14 @@ void writeUserBlock(FlashStruct *mem, int addr, int numbytes) printf("Error while writing data to disk. **File is potentially corrupt!**\n"); } } - globals.Flags.flash_write_in_progress = FALSE; + globals.Sys.flash_write_in_progress = FALSE; } else { printf("Could not backup current file. **Write did not happen!!!**\n"); } } } - g_mutex_unlock (&mutex); + g_static_mutex_unlock (&mutex); } @@ -333,9 +332,6 @@ static void initFlashValues(FlashStruct *mem) { int i,j,k,m; float power_of_ten, power_of_two; - float base_number; - - base_number=11; mem->flash_start=1; mem->turn_on_dly=5; @@ -344,9 +340,7 @@ static void initFlashValues(FlashStruct *mem) mem->ChanKey_logic_level=0; strcpy(mem->model_num,"unprogrammed"); - strcpy(mem->serial_num,"no S/N"); - strcpy(mem->password,"default"); - strcpy(mem->username,"admin"); + strcpy(mem->serial_num,"00000"); mem->fully_programmed=Being_Programmed; @@ -358,11 +352,11 @@ static void initFlashValues(FlashStruct *mem) mem->telnet_logon_timeout=30; /* thirty seconds */ mem->baud = 1200; - mem->parity = rs232_parity_none; - mem->stopbits = 1; - mem->databits = 8; + mem->parity = rs232_parity_none; // no longer used + mem->stopbits = 1; // no longer used + mem->databits = 8; // no longer used mem->hardhand = 1; - mem->echo = 1; + mem->echo = 1; // no longer used mem->on_off_used=1; @@ -443,35 +437,34 @@ static void initFlashValues(FlashStruct *mem) temp_int_prf=dac_max; mem->period_pwl_time[i][j][k][m]=(47e-9*power_of_ten)+41e-9; - mem->pw_pwl_time[i][j][k][m]=(base_number*0.7e-9*power_of_ten)+5e-9; - mem->delay_pwl_time[i][j][k][m]=(base_number*0.7e-9*power_of_ten)+7.6e-9; - mem->burst_pwl_time[i][j][k][m]=(2*base_number*1.0e-9*power_of_ten)+25e-9; + mem->pw_pwl_time[i][j][k][m]=(6e-9*power_of_ten)+5e-9; + mem->delay_pwl_time[i][j][k][m]=(6e-9*power_of_ten)+10e-9; + mem->burst_pwl_time[i][j][k][m]=(22e-9*power_of_ten)+25e-9; } else if (m==1) { - temp_int_pw_dly=dac_max/3; + temp_int_pw_dly=dac_max/2.15; temp_int_prf=dac_max/2.15; - mem->period_pwl_time[i][j][k][m]=(1e-7*power_of_ten)+50e-9; - - mem->pw_pwl_time[i][j][k][m]=(3*base_number*0.7e-9*power_of_ten)+10e-9; - mem->delay_pwl_time[i][j][k][m]=(3*base_number*0.7e-9*power_of_ten)+17e-9; - mem->burst_pwl_time[i][j][k][m]=(3*base_number*1.0e-9*power_of_ten)+10e-9; + mem->period_pwl_time[i][j][k][m]=(100e-9*power_of_ten)+50e-9; + mem->pw_pwl_time[i][j][k][m]=(14e-9*power_of_ten)+10e-9; + mem->delay_pwl_time[i][j][k][m]=(14e-9*power_of_ten)+30e-9; + mem->burst_pwl_time[i][j][k][m]=(33e-9*power_of_ten)+10e-9; } else if (m==2) { - temp_int_pw_dly=dac_min; + temp_int_pw_dly=dac_max/4.6; temp_int_prf=dac_max/4.6; - mem->period_pwl_time[i][j][k][m]=(2.3e-7*power_of_ten)+100e-9; - mem->pw_pwl_time[i][j][k][m]=(base_number*0.7e-8*power_of_ten)+40e-9; - mem->delay_pwl_time[i][j][k][m]=(base_number*0.7e-8*power_of_ten)+40e-9; - mem->burst_pwl_time[i][j][k][m]=(base_number*1.0e-8*power_of_ten)+10e-9; + mem->period_pwl_time[i][j][k][m]=(230e-9*power_of_ten)+100e-9; + mem->pw_pwl_time[i][j][k][m]=(28e-9*power_of_ten)+20e-9; + mem->delay_pwl_time[i][j][k][m]=(28e-9*power_of_ten)+60e-9; + mem->burst_pwl_time[i][j][k][m]=(50e-9*power_of_ten)+10e-9; } else if (m==3) { - temp_int_pw_dly=0; + temp_int_pw_dly=dac_min; temp_int_prf=dac_min; - mem->period_pwl_time[i][j][k][m]=(4.7e-7*power_of_ten)+160e-9; - mem->pw_pwl_time[i][j][k][m]=0.0; - mem->delay_pwl_time[i][j][k][m]=0.0; - mem->burst_pwl_time[i][j][k][m]=0.0; + mem->period_pwl_time[i][j][k][m]=(470e-9*power_of_ten)+160e-9; + mem->pw_pwl_time[i][j][k][m]=(70e-9*power_of_ten)+40e-9; + mem->delay_pwl_time[i][j][k][m]=(70e-9*power_of_ten)+90e-9; + mem->burst_pwl_time[i][j][k][m]=(110e-9*power_of_ten)+10e-9; } else { temp_int_pw_dly=0; temp_int_prf=0; @@ -736,6 +729,7 @@ static void initFlashValues(FlashStruct *mem) mem->vcc2_min[i]=3.0; mem->use_high_ampl_ranges_for_high_pw_ranges[i]=0; + mem->couple_first_N_pw_ranges_to_ampl_ranges[i]=0; } mem->relay_delay_in_sec=0.5; @@ -13,7 +13,10 @@ GlobalStruct globals = { .Registers.last_relay_driver_settings[1] = -1, .Registers.last_relay_driver_settings[2] = -1, - .Registers.gpib_buffer[0] = 0 + .Registers.gpib_input_buffer[0] = 0, + .Registers.pending_output_message = NULL, + + .VxiLocks.locked_network_server = NO_SERVER_LOCKED }; @@ -87,20 +87,11 @@ #define SelfCalError 73 #define NetworkNotFound 74 #define ThisShouldntHappen 75 +#define Startup_Not_Finished 76 #define YES 1 #define NO 0 - -#define LOCS_ctrl 0 -#define LWLS_ctrl 1 -#define REMS_ctrl 2 -#define RWLS_ctrl 3 -#define RS232_ctrl 4 -#define TELNET_ctrl 5 -#define WEB_ctrl 6 // FIXME - - #define max_commands_in_input 12 #define max_output_length 512 #define max_channels 2 @@ -195,9 +186,9 @@ #define ROUTE_PRIMARY 0 #define ROUTE_SECONDARY 1 -#define rs232_parity_none 0 -#define rs232_parity_odd 1 -#define rs232_parity_even 2 +#define rs232_parity_none 0 // no longer used +#define rs232_parity_odd 1 // no longer used +#define rs232_parity_even 2 // no longer used #define smallest_allowed_number 1.0e-18 #define zero_equiv_timing 1e-10 @@ -252,8 +243,8 @@ #define Submenu2_load 1500 #define Submenu2_rs232 1600 #define Submenu2_rs232_baud 1700 -#define Submenu2_rs232_databits 1800 -#define Submenu2_rs232_parity 1900 +#define Submenu2_rs232_databits 1800 // no longer used +#define Submenu2_rs232_parity 1900 // no longer used #define Submenu2_rs232_stopbits 2000 #define Submenu2_rs232_hardhand 2100 #define Submenu2_rs232_echo 2200 @@ -284,7 +275,8 @@ typedef struct { int ques_enable_register; /* for stat:enable command */ int avrq_reg; int last_rise_time_relay_setting; - char gpib_buffer[max_gpib_input_length]; + char gpib_input_buffer[max_gpib_input_length]; + gchar *pending_output_message; } HWregStruct; @@ -297,25 +289,10 @@ typedef struct { typedef struct { - int update_freq; - int update_func; - int update_delay; - int update_pw; int update_amp; int update_os; int update_zout; int update_load; - int update_output; - int update_inv; - int update_gate; - int update_logic_level; - int update_routes; - int update_burst_count; - int update_burst_time; - int update_rise_time; - int update_soft_current_limit; - int update_slew; - int update_whole_main_menu; } ChangeStruct; @@ -328,7 +305,7 @@ typedef struct { float avg_change; int total_errors; float total_max_change; - char response[max_output_length]; + GString *response; } CalStruct; @@ -397,8 +374,8 @@ typedef struct { short spare2; /* 59 */ char ChanKey_route; /* 61 */ char on_off_used; /* 62 */ - char password[32]; /* 63 */ - char username[32]; /* 95 */ + char password[32]; /* 63 - no longer used */ + char username[32]; /* 95 - no longer used */ char pcb116c_mon; /* 127 */ @@ -407,11 +384,11 @@ typedef struct { char warn_even_if_output_off; /* 129 */ int baud; /* 130 */ - char parity; - char stopbits; - char databits; + char parity; // no longer used + char stopbits; // no longer used + char databits; // no longer used char hardhand; - char echo; + char echo; // no longer used char spare1[23]; /* 139 */ @@ -716,6 +693,11 @@ typedef struct { char use_high_ampl_ranges_for_high_pw_ranges[max_channels]; /* addr 10066 - for AVMP-4 */ + char couple_first_N_pw_ranges_to_ampl_ranges[max_channels]; // addr 10068 + // for example, if N = 2 (as for AVR-E3-B-R5-N-M5) + // PG A = pw range 0, ampl range 0 + // PG B = pw range 1, ampl range 1 + // PG C = pw range 2+, ampl range 2 char spare_end; char flash_end; @@ -766,16 +748,23 @@ typedef struct { // note flags with non-zero default/reset values in globals.c // for example, do_check_settings=1 by default +// These flags are reset by Main_Rst typedef struct { int extended_ampl_min_max; int do_check_settings; int flash_writes_suspended; int force_output_fully_off; - int shutdown_started; - int flash_write_in_progress; } FlagStruct; +// These flags are NOT reset by Main_Rst, and default to 0 +typedef struct { + int shutdown_started; + int flash_write_in_progress; + int startup_complete; +} SysFlagStruct; + + typedef struct { long startup_timer_value; long last_activity_at[max_channels]; @@ -784,6 +773,31 @@ typedef struct { } TimeStruct; +// maximum number of ssh/getty sessions. +// same as max number of vxi sessions +#define MAX_SESSIONS 8 + +typedef struct { + int terminal_connections; + int vxi_connections; + int vxi_service_request; + int gpib_remote; + int gpib_lock; +} RemoteStruct; + + +typedef struct { + int beaglebone; + int gpib; +} HWDetectStruct; + + +#define NO_SERVER_LOCKED -1 +typedef struct { + int command_in_progress; + int locked_network_server; +} LockStruct; + typedef struct { ConstraintsStruct Constraints; ChannelStruct ChannelState[max_channels]; @@ -793,9 +807,12 @@ typedef struct { ErrorStruct Errors; FlagStruct Flags; FlagStruct DefaultFlags; + SysFlagStruct Sys; TimeStruct Timers; MenuStatusStruct MenuStatus; - int control_mode; // FIXME and all instances of control_mode + RemoteStruct Remote; + HWDetectStruct HWDetect; + LockStruct VxiLocks; } GlobalStruct; @@ -3,6 +3,7 @@ #include "flash.h" #include "error_utils.h" #include "bus.h" +#include <glib.h> /* TNT Configuration --------------------------------------------------------*/ @@ -11,16 +12,13 @@ #define max_gpib_input_length 512 -#define READ_EOS_BYTE 0x00 /* EOS byte for reads/inputs/receives*/ -#define WRITE_EOS_BYTE 0x00 /* EOS byte for writes/outputs/sends */ +#define READ_EOS_BYTE 0x00 /* EOS byte for reads/inputs/receives*/ +#define WRITE_EOS_BYTE 0x00 /* EOS byte for writes/outputs/sends */ #define USE_EIGHT_BIT_EOS_COMPARE NO /* Compare EOS byte 7 or 8 bits */ #define USE_TRANSMIT_EOI_WITH_EOS NO /* Send EOI with EOS byte (writes) */ -#define USE_HIGH_SPEED_T1 NO /* Short T1 delay while doing three wire handshaking */ +#define USE_HIGH_SPEED_T1 NO /* Short T1 delay while doing three wire handshaking */ -/* Miscellaneous Handlers */ -#define USE_SPOLL_BIT NO /* STBO (SPOLL) - Serial Poll */ - /* TNT Hardware Parameters */ #define TNT_BASE_ADDRESS 0x4100 /* Board Base I/O address */ @@ -28,28 +26,28 @@ /* TNT Constants ------------------------------------------------------------*/ #define YES 1 -#define ENABLE 1 +#define ENABLE 1 #define SET 1 #define NO 0 -#define NONE 0 -#define DISABLE 0 -#define CLEAR 0 -#define INPUT 4 +#define NONE 0 +#define DISABLE 0 +#define CLEAR 0 +#define INPUT 4 #define INPUT_BYTE 16 -#define OUTPUT 2 +#define OUTPUT 2 #define INTERFACE 1 /* Interface Status Constants */ -#define ERR (1<<15) +#define ERR (1<<15) #define TIMO (1<<14) -#define END (1<<13) -#define EOS (1<<12) -#define RQS (1<<11) -#define IFC (1<<10) +#define END (1<<13) +#define EOS (1<<12) +#define RQS (1<<11) +#define IFC (1<<10) #define SPOLL (1<<9) #define UCMPL (1<<8) -#define LOK (1<<7) -#define REM (1<<6) +#define LOK (1<<7) +#define REM (1<<6) #define ASYNC (1<<5) #define DTAS (1<<4) #define DCAS (1<<3) @@ -58,7 +56,7 @@ #define NACS (1<<0) #define SYNC 0 #define NONE 0 -#define EOI END +#define EOI END /* Error Codes */ @@ -80,9 +78,9 @@ * Define TNT register map and TL related bits and functions * * FORMAT: - * register address - * B_bits value - * F_function value (F_field) + * register address + * B_bits value + * F_function value (F_field) * ****************************************************************************/ @@ -111,7 +109,7 @@ #define B_rem (1<<4) #define R_isr3 0x1a -#define B_x (1<<7) +#define B_x (1<<7) #define B_intsrc2 (1<<6) #define B_nff (1<<3) #define B_nef (1<<2) @@ -133,7 +131,7 @@ #define R_admr 0x08 -#define F_noaddress 0x30 +#define F_noaddress 0x30 #define F_normalprimary 0x31 #define R_adr 0x0c @@ -167,8 +165,6 @@ #define F_clrERR 0x57 /* Hidden Auxillary Registers */ -#define B_u (1<<4) -#define B_s (1<<3) #define HR_auxra 0x80 #define F_normal 0x00 @@ -185,9 +181,6 @@ #define HR_auxrb 0xa0 #define B_hst1 (1<<2) -#define HR_auxre 0xc0 -#define B_dhdc (1<<0) - #define HR_auxri 0xe0 #define B_ustd (1<<3) @@ -202,6 +195,8 @@ #define R_misc 0x15 #define R_sts1 0x10 +#define R_sts2 0x1c + #define B_halt (1<<1) #define R_cfg 0x10 @@ -214,8 +209,6 @@ #define F_input_config (B_in|B_tmoe|B_timbytn|B_ccen|B_8bit) #define F_output_config (B_tmoe|B_timbytn|B_8bit) -#define R_dsr 0x11 - #define R_hssel 0x0d #define B_go2sids (1<<5) #define F_onechip 0x01 @@ -226,25 +219,21 @@ #define R_fifob 0x18 #define R_sasr 0x1b - #define R_cmdr 0x1c #define F_softreset 0x22 #define F_resetfifo 0x10 #define F_stop 0x08 #define F_go 0x04 -#define R_bsr 0x1f /* --------------------------------------------------------------------------*/ /* TNT4882 GLOBAL VARIABLES -------------------------------------------------*/ -int is_gpib; - -int INTERFACE_ERROR; /* Error Code */ -int INTERFACE_STATUS; /* Interface Status */ -unsigned char MR_4882_status[5]; /* 4882 status memory registers */ +int INTERFACE_ERROR; /* Error Code */ +int INTERFACE_STATUS; /* Interface Status */ +unsigned char MR_4882_status[5]; /* 4882 status memory registers */ unsigned long int DATA_COUNT; /* Transfer count */ unsigned long int Requested_Count; /* Requested transfer count */ @@ -271,61 +260,63 @@ void TNT_4882_Status(int status_register,unsigned int byte,int operation) { int set_srq; - MR_4882_status[STB] = TNT_In(R_spsr); /* Get STB */ + MR_4882_status[STB] = TNT_In(R_spsr); // Get STB switch (operation) { case SET: - /* Cannot set SRQ directly */ + // Cannot set SRQ directly if((status_register==STB)||(status_register==SRE)) { byte&=~0x40; } - MR_4882_status[status_register]|= byte;/* OR in new register value */ + MR_4882_status[status_register]|= byte; // OR in new register value if(status_register==IST) { - TNT_Out(R_auxmr,F_ist1); /* if IST set IST bit */ + TNT_Out(R_auxmr,F_ist1); // if IST set IST bit } break; case CLEAR: - MR_4882_status[status_register]&=~byte; /* ~AND requested bits */ + MR_4882_status[status_register]&=~byte; // ~AND requested bits if(status_register==IST) { - TNT_Out(R_auxmr,F_ist0); /* if IST clear IST bit */ + TNT_Out(R_auxmr,F_ist0); // if IST clear IST bit } break; default: - TNT_Gen_Error(EARG); /* Neither SET/CLEAR then EARG */ + TNT_Gen_Error(EARG); // Neither SET/CLEAR then EARG break; } - /* If ESE&ESR set ESB bit */ + // If ESE&ESR set ESB bit MR_4882_status[STB]|=(MR_4882_status[ESE]&MR_4882_status[ESR])? 0x20 : 0; - /* If STB&SRE set RQS bit */ + // If STB&SRE set RQS bit set_srq = (MR_4882_status[STB]&MR_4882_status[SRE])? TRUE : FALSE; - if(set_srq) { /* If SRQ desired */ - TNT_Out(R_auxmr,F_reqt); /* Set request true */ - } else { /* Else */ - TNT_Out(R_auxmr,F_reqf); /* Set request false */ + if(set_srq) { // If SRQ desired + globals.Remote.vxi_service_request = 1; + TNT_Out(R_auxmr,F_reqt); // Set request true + } else { + globals.Remote.vxi_service_request = 0; + TNT_Out(R_auxmr,F_reqf); // Set request false } - TNT_Out(R_spmr,MR_4882_status[STB]); /* Set new serial poll byte */ + TNT_Out(R_spmr,MR_4882_status[STB]); // Set new serial poll byte } /**************************************************************************** * * TNT_INT_STATUS(): Used to update INTERFACE_STATUS word by reading - * R_isr0,R_isr1,R_isr2,R_isr3,R_adsr,R_spmr and - * updating the appropriate INTERFACE_STATUS bits. + * R_isr0,R_isr1,R_isr2,R_isr3,R_adsr,R_spmr and + * updating the appropriate INTERFACE_STATUS bits. * * INTERFACE_STATUS bits: * - * ERR (1<<15) Error - Check INTERFACE_ERROR for error - * TIMO (1<<14) Timeout - If timeouts are used - * END (1<<13) End/EOI/EOS - End of transmition received + * ERR (1<<15) Error - Check INTERFACE_ERROR for error + * TIMO (1<<14) Timeout - If timeouts are used + * END (1<<13) End/EOI/EOS - End of transmition received * EOS (1<<12) End of String - End of string received * RQS (1<<11) Requesting Service - TNT asserting SRQ line * IFC (1<<10) Interface Clear - Interface Clear Asserted @@ -335,7 +326,7 @@ void TNT_4882_Status(int status_register,unsigned int byte,int operation) * LOK (1<<7) Local Lockout - Lockout front panel controls * REM (1<<6) Remote Programming - TNT in remote programming state * ASYNC (1<<5) Asyncronous I/O - NOT USED IN NON-INT ESP - * DTAS (1<<4) Trigger Active State - Requested Device Trigger + * DTAS (1<<4) Trigger Active State - Requested Device Trigger * DCAS (1<<3) Clear Active State - Requested Device Clear * LACS (1<<2) Listener Active - TNT listen addressed * TACS (1<<1) Talker Active - TNT talk addressed @@ -356,27 +347,26 @@ static int TNT_INT_STATUS(void) mr_adsr=TNT_In(R_adsr); /* Read status register adsr */ INTERFACE_STATUS&=(UCMPL|END|EOS|TIMO|ERR); /* Maintain I/O bits */ - /* These are cleared at the */ - /* beginning of a new I/O call */ + // These are cleared at the beginning of a new I/O call - /* Get new status */ - INTERFACE_STATUS|=((mr_isr0&B_to) ?TIMO :0)|((mr_isr2&B_rem) ?REM :0) - |((mr_isr1&B_end) ?END :0)|((mr_isr0&B_eos) ?EOS :0) - |((mr_spsr&B_pend)?RQS :0)|((mr_isr0&B_ifc) ?IFC :0) - |((mr_isr0&B_stbo)?SPOLL:0)|((mr_isr2&B_lok) ?LOK :0) - |((mr_isr1&B_det) ?DTAS :0)|((mr_isr1&B_dec) ?DCAS:0) - |((mr_adsr&B_ta) ?TACS :0)|((mr_adsr&B_la) ?LACS:0); + // Get new status + INTERFACE_STATUS|= ((mr_isr0&B_to) ?TIMO :0)|((mr_isr2&B_rem) ?REM :0) + |((mr_isr1&B_end) ?END :0)|((mr_isr0&B_eos) ?EOS :0) + |((mr_spsr&B_pend)?RQS :0)|((mr_isr0&B_ifc) ?IFC :0) + |((mr_isr0&B_stbo)?SPOLL:0)|((mr_isr2&B_lok) ?LOK :0) + |((mr_isr1&B_det) ?DTAS :0)|((mr_isr1&B_dec) ?DCAS:0) + |((mr_adsr&B_ta) ?TACS :0)|((mr_adsr&B_la) ?LACS:0); INTERFACE_STATUS|=((INTERFACE_STATUS&(LACS|TACS)) ? 0:NACS); - return INTERFACE_STATUS; /* Return status */ + return INTERFACE_STATUS; } /**************************************************************************** * * TNT_Gen_Error(): Used to Update INTERFACE_ERROR. INTERFACE_ERROR is - * only valid when ERR is set in INTERFACE_STATUS. + * only valid when ERR is set in INTERFACE_STATUS. * * INTERFACE_ERROR values: * @@ -404,37 +394,34 @@ static void TNT_Gen_Error(int code) /**************************** INITIALIZATION ******************************** * * GPIB_initialize(): Sets the TNT into a known initialized state, - * clears global values (mask registers,status words), - * and loads current addressing setup. + * clears global values (mask registers,status words), + * and loads current addressing setup. * - * Normally, this function is executed once at power - * up, however it may be used to reinitialize the - * interface during operation. + * Normally, this function is executed once at power + * up, however it may be used to reinitialize the + * interface during operation. * ****************************************************************************/ /*----------------------------------------------------------------------------------------------------------*/ void GPIB_initialize(void) { - int i; - INTERFACE_STATUS=0; /* Initialize Globals to zero */ INTERFACE_ERROR=0; DATA_COUNT=0; Requested_Count=0; - TNT_Out(R_cmdr,F_softreset); /* Reset FIFOS */ - - TNT_Out(R_spmr ,0x80); /* This sequence of commands */ - - if (TNT_In(R_spmr) == 0x80) { - is_gpib = 1; + // test to detect TNT chip + if ((TNT_In(R_sts2) & 0xB0) == 0x90) { + globals.HWDetect.gpib = 1; } else { - is_gpib = 0; + globals.HWDetect.gpib = 0; printf ("Error: TNT4882 chip not found\n"); return; } + TNT_Out(R_cmdr,F_softreset); /* Reset FIFOS */ + TNT_Out(R_spmr ,0x80); /* This sequence of commands */ TNT_Out(R_auxmr,0x80); /* insures that the TNT */ TNT_Out(R_auxmr,0x99); /* will be in the normal 7210 */ TNT_Out(R_keyrg,0); /* mode and not 9914 */ @@ -469,17 +456,17 @@ void GPIB_initialize(void) static void TNT_Adr_Mode() { TNT_Out(R_admr,F_noaddress); /* Clear address mode */ - TNT_Out(R_adr,B_dt|B_dl); /* Disable talk & listener */ + TNT_Out(R_adr,B_dt|B_dl); /* Disable talk & listener */ TNT_Out(R_adr,B_ars|B_dt|B_dl); /* capabilities */ - TNT_Out(R_auxmr,F_lut); /* Untalk TNT4882 */ - TNT_Out(R_auxmr,F_lul); /* Unlisten TNT4882 */ + TNT_Out(R_auxmr,F_lut); /* Untalk TNT4882 */ + TNT_Out(R_auxmr,F_lul); /* Unlisten TNT4882 */ TNT_Out(R_admr,F_normalprimary); /* Set single primary address mode*/ } void GPIB_change_address(int new_address) { - if (!is_gpib) { + if (!globals.HWDetect.gpib) { return; } @@ -495,59 +482,63 @@ void GPIB_change_address(int new_address) static void TNT_Setup_IO(int IO_type, unsigned long int cnt, int term) { - unsigned long int twos_cnt; /* Obtain the twos compliment cnt */ + unsigned long int twos_cnt; // Obtain the twos compliment cnt twos_cnt=-cnt; - Requested_Count=cnt; /* Save requested transfer cnt */ + Requested_Count=cnt; // Save requested transfer cnt - TNT_Out(R_cmdr,F_resetfifo); /* Reset TNT fifos */ + TNT_Out(R_cmdr,F_resetfifo); // Reset TNT fifos - TNT_Out(R_cnt0, (char)(twos_cnt)); /* Load twos compliment count */ - TNT_Out(R_cnt1, (char)(twos_cnt>>8)); /* into TNT count registers */ + TNT_Out(R_cnt0, (char)(twos_cnt)); // Load twos compliment count + TNT_Out(R_cnt1, (char)(twos_cnt>>8)); // into TNT count registers TNT_Out(R_cnt2, (char)(twos_cnt>>16)); TNT_Out(R_cnt3, (char)(twos_cnt>>24)); - TNT_Out(R_imr0,B_glint); /* Set write to imr0 to be sure */ - TNT_Out(R_auxmr,HR_auxrj|0); /* B_to is cleared */ + TNT_Out(R_imr0,B_glint); // Set write to imr0 to be sure + TNT_Out(R_auxmr,HR_auxrj|0); // B_to is cleared switch(IO_type) { case INPUT_BYTE: - TNT_Out(R_imr1, B_end); /* End transfer on eoi or eos */ - - TNT_Out(R_eosr, READ_EOS_BYTE); /* Set eos byte */ + TNT_Out(R_imr1, B_end); // End transfer on eoi or eos + TNT_Out(R_eosr, READ_EOS_BYTE); // Set eos byte TNT_Out(R_auxmr,HR_auxra|F_hlde|((term&EOS)?B_endoneos:0)); - /* Configure for byte input */ + + // Configure for byte input TNT_Out(R_cfg , F_input_config&~B_16bit); - /* Holdoff on end & enable eos */ - TNT_Out(R_auxmr,F_rhdf); /* Release holdoff */ - TNT_Out(R_cmdr, F_go); /* Start transfer state machine */ + + // Holdoff on end & enable eos + TNT_Out(R_auxmr,F_rhdf); // Release holdoff + TNT_Out(R_cmdr, F_go); // Start transfer state machine break; case INPUT: - TNT_Out(R_imr1, B_end); /* End transfer on eoi or eos */ - TNT_Out(R_eosr, READ_EOS_BYTE); /* Set eos byte */ + TNT_Out(R_imr1, B_end); // End transfer on eoi or eos + TNT_Out(R_eosr, READ_EOS_BYTE); // Set eos byte TNT_Out(R_auxmr,HR_auxra|F_hlde|((term&EOS)?B_endoneos:0)); - TNT_Out(R_cfg , F_input_config); /* Configure for *byte* input */ + TNT_Out(R_cfg , F_input_config); // Configure for *byte* input + /* Holdoff on end & enable eos */ - TNT_Out(R_auxmr,F_rhdf); /* Release holdoff */ - TNT_Out(R_cmdr, F_go); /* Start transfer state machine */ + TNT_Out(R_auxmr,F_rhdf); // Release holdoff + TNT_Out(R_cmdr, F_go); // Start transfer state machine break; case OUTPUT: - TNT_Out(R_imr1, B_err); /* End transfer on err */ - TNT_Out(R_eosr, WRITE_EOS_BYTE); /* Set EOS byte */ - /* Holdoff on all & enable EOS */ + TNT_Out(R_imr1, B_err); // End transfer on err + TNT_Out(R_eosr, WRITE_EOS_BYTE); // Set EOS byte + + // Holdoff on all & enable EOS TNT_Out(R_auxmr,HR_auxra|F_hlda|((term&EOS)?B_xeoiweos:0)); - /* Configure for *byte* output */ + + // Configure for *byte* output TNT_Out(R_cfg , F_output_config|((term)?B_ccen:0)); - TNT_Out(R_auxmr,F_hldi); /* Hold off immediately */ - TNT_Out(R_cmdr, F_go); /* Start transfer state machine */ + TNT_Out(R_auxmr,F_hldi); // Hold off immediately + TNT_Out(R_cmdr, F_go); // Start transfer state machine break; default: - TNT_Gen_Error(EARG); /* If IO_type incorrect issue EARG*/ + TNT_Gen_Error(EARG); // If IO_type incorrect issue EARG break; } } @@ -555,24 +546,24 @@ static void TNT_Setup_IO(int IO_type, unsigned long int cnt, int term) static void TNT_DONE_Handler(int IO_type,unsigned long int *count_sent) { - TNT_Out(R_cmdr,F_stop); /* Stop fifos */ - TNT_Out(R_cmdr,F_resetfifo); /* Reset the fifos */ + TNT_Out(R_cmdr,F_stop); // Stop fifos + TNT_Out(R_cmdr,F_resetfifo); // Reset the fifos - if(TNT_In(R_isr1)&B_end) { /* If we received an END */ - TNT_Out(R_auxmr,F_clrEND); /* Clear status bit */ + if(TNT_In(R_isr1)&B_end) { // If we received an END + TNT_Out(R_auxmr,F_clrEND); // Clear status bit } if(TNT_In(R_isr1)&B_err) { - TNT_Gen_Error(ENOL); /* No listeners */ - TNT_Out(R_auxmr,F_clrERR); /* Clear error bit */ + TNT_Gen_Error(ENOL); // No listeners + TNT_Out(R_auxmr,F_clrERR); // Clear error bit if(IO_type==OUTPUT) { - TNT_Out(R_hssel,F_onechip|B_go2sids); /* if error set to idle state. */ + TNT_Out(R_hssel,F_onechip|B_go2sids); // if error set to idle state. TNT_Out(R_hssel,F_onechip); } } - *count_sent = TNT_DATA_COUNT(); /* Obtain transfer count */ + *count_sent = TNT_DATA_COUNT(); // Obtain transfer count } @@ -604,14 +595,14 @@ static unsigned char TNT_In(int reg) static int TNT_input_bav(void) { - /* is a byte available (bav) in the TNT4882 FIFOs? Used mostly for GPIB reads */ + // is a byte available (bav) in the TNT4882 FIFOs? Used mostly for GPIB reads return (int) TNT_In(R_isr3)&B_nef; } static int TNT_update_brq(void) { - /* is the GPIB requesting data from the TNT4882? */ + // is the GPIB requesting data from the TNT4882? int state_SGNS; int state_TACS; @@ -622,7 +613,7 @@ static int TNT_update_brq(void) each data request, so some memory is required to avoid generating multiple, stateless brq messages. */ - if (!prev_brq) { /* prev_brq=0 */ + if (!prev_brq) { prev_brq=state_SGNS; return state_SGNS; } else { @@ -637,13 +628,20 @@ int GPIB_check_for_device_clear_signal(void) /* added by MJC - June 20/06 */ /* reset interface if a device clear is received */ - if (!is_gpib) { + if (!globals.HWDetect.gpib) { return FALSE; } if (TNT_INT_STATUS() & DCAS) { TNT_Out(R_auxmr,F_clrDEC); + + TNT_4882_Status(STB,0x10,CLEAR); // Clear MAV bit + g_free (globals.Registers.pending_output_message); + globals.Registers.pending_output_message = NULL; + + TNT_Holdoff_off(); TNT_INT_STATUS(); + return TRUE; } else { return FALSE; @@ -655,24 +653,30 @@ int GPIB_check_for_messages(char *gpib_buf) { #define ib_empty (!(strlen(gpib_buf))) - if (!is_gpib) { + if (!globals.HWDetect.gpib) { return FALSE; } - /* If the GPIB has requested data, and no output messages are in the TNT4882 FIFOs, generate a query error */ + // If the GPIB has requested data, and no output messages + // are in the TNT4882 FIFOs, generate a query error + if (TNT_update_brq() && !TNT_input_bav() && ib_empty) { queue_error_for_gpib_only(query_error_unterminated); } - /* If the TNT4882 is talk addressed, the controller must be still reading output data in the TNT4882 - FIFOs. Wait until this process has completed and the TNT4882 is listen addressed. */ + // If the TNT4882 is talk addressed, the controller must + // be still reading output data in the TNT4882 FIFOs. + // Wait until this process has completed and the TNT4882 + // is listen addressed. + if ( (TNT_In(R_adsr)&B_ta) && (TNT_In(R_isr3)&B_nef) && !(TNT_In(R_cfg)&B_in)) { - return OK; /* exit if not listen addressed */ + // exit if not listen addressed + return OK; } - - /* if no I/O is begin done, set up for input. Note that TLCHLTE must be set to zero, so that the */ - /* HALT signal is set only by the STOP and GO commands. */ + // if no I/O is begin done, set up for input. Note that TLCHLTE + // must be set to zero, so that the HALT signal is set only by + // the STOP and GO commands. if (TNT_In(R_sts1)&B_halt) { cnt=max_gpib_input_length-8; gpib_buf[0]=0; @@ -680,37 +684,38 @@ int GPIB_check_for_messages(char *gpib_buf) TNT_Setup_IO(INPUT,cnt,EOI|EOS); } - /* is data available to read? */ + // is data available to read? return (TNT_In(R_isr3)&B_nef) && (TNT_In(R_cfg)&B_in); } int GPIB_handle_new_input(char *gpib_buf) { - if (!is_gpib) { + if (!globals.HWDetect.gpib) { return FALSE; } - /* read until done or buffers empty. Then reset DAC holdoff */ + // read until done or buffers empty. Then reset DAC holdoff - unsigned long int count_sent; /* Local count variable */ + unsigned long int count_sent; // Local count variable int i; char *buffer_pos; buffer_pos = gpib_buf; - count_sent=0; /* Clear I/O status bits */ - DATA_COUNT=0; /* Clear count global */ + count_sent=0; // Clear I/O status bits + DATA_COUNT=0; // Clear count global - /* read FIFOs until transaction completed or interrupted */ - while( !( INTERFACE_STATUS & DCAS) /* device clear */ - && !( !TNT_input_bav() && (INTERFACE_STATUS & END)) /* proper transaction end */ - && !( !TNT_input_bav() && TNT_In(R_isr3)&B_done) /* proper transaction end */ - && !( !TNT_input_bav() && (INTERFACE_STATUS & TIMO)) /* improper timeout */ - && !( !TNT_input_bav() && TNT_update_brq() && ib_empty) /* brq message true, GPIB requesting data */ + // read FIFOs until transaction completed or interrupted + while( !( INTERFACE_STATUS & DCAS) // device clear + && !( !TNT_input_bav() && (INTERFACE_STATUS & END)) // proper transaction end + && !( !TNT_input_bav() && TNT_In(R_isr3)&B_done) // proper transaction end + && !( !TNT_input_bav() && (INTERFACE_STATUS & TIMO)) // improper timeout + && !( !TNT_input_bav() && TNT_update_brq() && ib_empty) // brq message true, + // GPIB requesting data ) { - /* choose the most efficient fifo-emptying method based on FIFO flags */ + // choose the most efficient fifo-emptying method based on FIFO flags switch(TNT_In(R_isr3)&(B_nff|B_intsrc2|B_nef)) { case (B_nef): case (B_nef|B_intsrc2): @@ -730,28 +735,29 @@ int GPIB_handle_new_input(char *gpib_buf) break; } - TNT_INT_STATUS(); /* Update to get current status */ + TNT_INT_STATUS(); // Update to get current status } - TNT_DONE_Handler(INPUT,&count_sent); /* Finish up and get count */ - DATA_COUNT+=count_sent; /* Update total transfer count */ - cnt-=count_sent; /* Update total requested count */ - buffer_pos=buffer_pos+((int) count_sent); /* Update buffer pointer */ + TNT_DONE_Handler(INPUT,&count_sent); // Finish up and get count + DATA_COUNT+=count_sent; // Update total transfer count + cnt-=count_sent; // Update total requested count + buffer_pos=buffer_pos+((int) count_sent); // Update buffer pointer - INTERFACE_STATUS|=UCMPL; /* Set the user complete bit */ + INTERFACE_STATUS|=UCMPL; // Set the user complete bit if (GPIB_check_for_device_clear_signal()) { - return FALSE; /* abandon if SDC, DCL */ + return FALSE; // abandon if SDC, DCL } if (TNT_update_brq() && !TNT_input_bav() && ib_empty) - /* abandon if brq with no commands to process */ + // abandon if brq with no commands to process { queue_error_for_gpib_only(query_error_unterminated); - prev_brq=1; /* reset brq */ - TNT_update_brq(); /* update it so that it doesn't get confused in idle state */ + prev_brq=1; // reset brq + TNT_update_brq(); // update it so that it doesn't get confused + // in idle state return FALSE; } @@ -762,151 +768,165 @@ int GPIB_handle_new_input(char *gpib_buf) static void TNT_RFD_Holdoff() { - /* holdoff accepting data until software has checked the state of the TNT4882 */ - TNT_Out(R_auxmr,F_hldi); /* set immediate RFD holdoff */ + // holdoff accepting data until software has checked the state of the TNT4882 + TNT_Out(R_auxmr,F_hldi); // set immediate RFD holdoff } static void TNT_Holdoff_off() { - TNT_Out(R_auxmr,F_rhdf); /* cancel immediate RFD holdoff */ + TNT_Out(R_auxmr,F_rhdf); // cancel immediate RFD holdoff } -int GPIB_send_query_response(char *out_buffer) +void GPIB_and_VXI_start_query_response(gpointer *ignore_this, char *in_string) { - if (!is_gpib) { - return OK; + g_assert (ignore_this == NULL); + g_assert (in_string != NULL); + + if (!globals.HWDetect.gpib) { + return; + } + + if (globals.Registers.pending_output_message != NULL) { + queue_error_for_gpib_only(query_error_interrupted); + g_free (globals.Registers.pending_output_message); + globals.Registers.pending_output_message = NULL; } - /* message must be available if this function has been called */ + globals.Registers.pending_output_message = g_strdup_printf ("%s\n", in_string); + TNT_4882_Status(STB,0x10,SET); // Set MAV bit +} - unsigned long int out_cnt; - unsigned long int count_sent; /* Local count variable */ - int i; - out_cnt = strlen (out_buffer); +void GPIB_finish_query_response() +{ + if (!globals.HWDetect.gpib) { + return; + } - TNT_4882_Status(STB,0x10,SET); /* Set MAV bit */ + if (globals.Registers.pending_output_message == NULL) { + return; + } + + // just a pointer + char *out_buffer = globals.Registers.pending_output_message; + int i; + unsigned long int out_cnt = strlen (out_buffer); + unsigned long int count_sent; // Local count variable TNT_INT_STATUS(); - /* if the TNT4882 isn't talk addressed, wait until it is, or until the GPIB sends a clear signal, - or until the GPIB writes more data to the TNT4882, generating a query error. */ - while (!(INTERFACE_STATUS&TACS)) { - TNT_RFD_Holdoff(); - if (INTERFACE_STATUS&DCAS) { - /* device has been cleared. return to idle state */ - TNT_4882_Status(STB,0x10,CLEAR); /* Clear MAV bit */ - TNT_Holdoff_off(); + // if the TNT4882 isn't talk addressed, wait until it is, or until the GPIB sends a clear signal, + // or until the GPIB writes more data to the TNT4882, generating a query error. - /* added by MJC - June 20/06 */ - /* reset interface if a device clear is received */ - TNT_Out(R_auxmr,F_clrDEC); - TNT_INT_STATUS(); + if (!(INTERFACE_STATUS&TACS)) { + TNT_RFD_Holdoff(); + if (GPIB_check_for_device_clear_signal()) { + return; - return OK; } else if (!TNT_input_bav()) { - /* if no bytes are available, we're still waiting for the GPIB to request data. Repeat loop. */ + // if no bytes are available, we're still waiting for the + // GPIB to request data. Repeat loop. TNT_Setup_IO(INPUT,out_cnt,EOI|EOS); TNT_INT_STATUS(); TNT_Holdoff_off(); + return; + } else { - /* abandon if input bytes available, and generate query error */ + // abandon if input bytes available, and generate query error TNT_Holdoff_off(); queue_error_for_gpib_only(query_error_interrupted); - TNT_4882_Status(STB,0x10,CLEAR); /* Clear MAV bit */ - prev_brq=1; /* reset brq */ - TNT_update_brq(); /* update it so that it doesn't get confused in idle state */ - return OK; + TNT_4882_Status(STB,0x10,CLEAR); // Clear MAV bit + prev_brq=1; // reset brq + TNT_update_brq(); // update it so that it doesn't get + return; // confused in idle state } - } - - TNT_Setup_IO(OUTPUT,out_cnt,EOI|EOS); - - count_sent=0; - INTERFACE_STATUS=0; /* Clear I/O status bits */ - DATA_COUNT=0; /* Clear count global */ + } else { + // We are talk-addressed. Send some data. - if(out_cnt==0) { - INTERFACE_STATUS|=UCMPL; - return OK; - } + TNT_Setup_IO(OUTPUT,out_cnt,EOI|EOS); - /* send data until completed or interrupted */ - while( !(INTERFACE_STATUS&(DCAS|TIMO|END|ERR|LACS)) - && !(TNT_In(R_isr3)&B_done) - ) { + count_sent=0; + INTERFACE_STATUS=0; // Clear I/O status bits + DATA_COUNT=0; // Clear count global - /* choose the most efficient fifo-filling method based on flags */ - switch(TNT_In(R_isr3)&(B_nff|B_intsrc2|B_nef)) { - case (B_nff): - case (B_nff|B_intsrc2): /* 16 words in fifo are empty */ - for(i=0; i<16; i++) { - TNT_Out(R_fifob,*((char *)(out_buffer++))); - } - break; + if(out_cnt==0) { + INTERFACE_STATUS|=UCMPL; + return; + } - case (B_nff|B_intsrc2|B_nef): /* 8 words in fifo are empty */ - for(i=0; i<8; i++) { + // send data until completed or interrupted + while( !(INTERFACE_STATUS&(DCAS|TIMO|END|ERR|LACS)) + && !(TNT_In(R_isr3)&B_done) + ) { + + // choose the most efficient fifo-filling method based on flags + switch(TNT_In(R_isr3)&(B_nff|B_intsrc2|B_nef)) { + case (B_nff): + case (B_nff|B_intsrc2): // 16 words in fifo are empty + for(i=0; i<16; i++) { + TNT_Out(R_fifob,*((char *)(out_buffer++))); + } + break; + + case (B_nff|B_intsrc2|B_nef): // 8 words in fifo are empty + for(i=0; i<8; i++) { + TNT_Out(R_fifob,*((char *)(out_buffer++))); + } + break; + + case (B_nff|B_nef): // 1 word in fifo is empty TNT_Out(R_fifob,*((char *)(out_buffer++))); + break; } - break; - case (B_nff|B_nef): /* 1 word in fifo is empty */ - TNT_Out(R_fifob,*((char *)(out_buffer++))); - break; + TNT_INT_STATUS(); // Get current status } - TNT_INT_STATUS(); /* Get current status */ - } - - TNT_DONE_Handler(OUTPUT,&count_sent); /* Finish up and get count */ - DATA_COUNT+=count_sent; /* Update total transfer count */ - out_cnt-=count_sent; /* Update total requested count */ - out_buffer=out_buffer+((int) count_sent); /* Update buffer pointer */ + TNT_DONE_Handler(OUTPUT,&count_sent); // Finish up and get count + DATA_COUNT+=count_sent; // Update total transfer count + out_cnt-=count_sent; // Update total requested count + out_buffer=out_buffer+((int) count_sent); // Update buffer pointer - INTERFACE_STATUS|=UCMPL; /* Set the user complete bit */ + INTERFACE_STATUS|=UCMPL; // Set the user complete bit - if (INTERFACE_STATUS&DCAS) { - TNT_4882_Status(STB,0x10,CLEAR); /* Clear MAV bit */ + g_free (globals.Registers.pending_output_message); + globals.Registers.pending_output_message = NULL; - /* added by MJC - June 20/06 */ - /* reset interface if a device clear is received */ - TNT_Out(R_auxmr,F_clrDEC); - TNT_INT_STATUS(); - - return OK; /* abandon if SDC or DCL */ - } + if (GPIB_check_for_device_clear_signal()) { + return; + } - if ((INTERFACE_STATUS&LACS) && (TNT_In(R_isr3)&B_nef)) { - /* abandon gracefully if listen-addressed with data in buffer */ - queue_error_for_gpib_only(query_error_interrupted); - TNT_4882_Status(STB,0x10,CLEAR); /* Clear MAV bit */ - prev_brq=1; /* reset brq */ - TNT_update_brq(); /* update it so that it doesn't get confused in idle state */ - TNT_Setup_IO(INPUT,cnt,EOI|EOS); - return OK; - } + if ((INTERFACE_STATUS&LACS) && (TNT_In(R_isr3)&B_nef)) { + // abandon gracefully if listen-addressed with data in buffer + queue_error_for_gpib_only(query_error_interrupted); + TNT_4882_Status(STB,0x10,CLEAR); // Clear MAV bit + prev_brq=1; // reset brq + TNT_update_brq(); // update it so that it doesn't get + // confused in idle state + TNT_Setup_IO(INPUT,cnt,EOI|EOS); + return; + } - if(DATA_COUNT>0) { - TNT_4882_Status(STB,0x10,CLEAR); /* Clear MAV bit */ - prev_brq=1; /* brq was active during send */ - TNT_update_brq(); /* update it so that it doesn't get confused in idle state */ + if(DATA_COUNT>0) { + TNT_4882_Status(STB,0x10,CLEAR); // Clear MAV bit + prev_brq=1; // brq was active during send */ + TNT_update_brq(); // update it so that it doesn't get + // confused in idle state + } } - - return OK; } void GPIB_check_remote_status (int *is_remote, int *is_lockout) { *is_remote = *is_lockout = 0; - if (!is_gpib) { + if (!globals.HWDetect.gpib) { return; } - TNT_INT_STATUS(); /* Update to get current status */ + TNT_INT_STATUS(); // Update to get current status if ((INTERFACE_STATUS&REM) == REM) { *is_remote = 1; } @@ -918,35 +938,25 @@ void GPIB_check_remote_status (int *is_remote, int *is_lockout) } -unsigned char GPIB_response_already_pending () -{ - if (!is_gpib) { - return 0; - } - - return TNT_In(R_spsr) & 0x10; -} - - void GPIB_go_to_local () { - if (!is_gpib) { + if (!globals.HWDetect.gpib) { return; } - TNT_Out(R_auxmr,0x05); /* issue TNT rtl command */ + TNT_Out(R_auxmr,0x05); // issue TNT rtl command return; } void GPIB_clear_events () { - if (!is_gpib) { + if (!globals.HWDetect.gpib) { return; } - TNT_4882_Status(ESR,0xff,CLEAR); /* Clear ESR register */ - TNT_4882_Status(STB,0x20,CLEAR); /* Clear ESB bit in STB */ + TNT_4882_Status(ESR,0xff,CLEAR); // Clear ESR register + TNT_4882_Status(STB,0x20,CLEAR); // Clear ESB bit in STB return; } @@ -969,10 +979,10 @@ unsigned int GPIB_get_ESE () } -unsigned int GPIB_get_STB () +unsigned int GPIB_and_VXI_get_STB () { - if (!is_gpib) { - return; + if (!globals.HWDetect.gpib) { + return 0; } return (TNT_In(R_spsr)&0xbf) | (((TNT_In(R_spsr)&0xbf) & MR_4882_status[SRE])?0x40:0); @@ -981,7 +991,7 @@ unsigned int GPIB_get_STB () void GPIB_set_ESR (unsigned int byte,int operation) { - if (!is_gpib) { + if (!globals.HWDetect.gpib) { return; } @@ -991,7 +1001,7 @@ void GPIB_set_ESR (unsigned int byte,int operation) void GPIB_set_SRE (unsigned int byte,int operation) { - if (!is_gpib) { + if (!globals.HWDetect.gpib) { return; } @@ -1001,7 +1011,7 @@ void GPIB_set_SRE (unsigned int byte,int operation) void GPIB_set_ESE (unsigned int byte,int operation) { - if (!is_gpib) { + if (!globals.HWDetect.gpib) { return; } @@ -1011,40 +1021,40 @@ void GPIB_set_ESE (unsigned int byte,int operation) void GPIB_Set_Execution_Error () { - if (!is_gpib) { + if (!globals.HWDetect.gpib) { return; } - TNT_4882_Status(3,0x10,1); + TNT_4882_Status(ESR,0x10,1); } void GPIB_Set_Command_Error () { - if (!is_gpib) { + if (!globals.HWDetect.gpib) { return; } - TNT_4882_Status(3,0x20,1); + TNT_4882_Status(ESR,0x20,1); } void GPIB_Set_Query_Error () { - if (!is_gpib) { + if (!globals.HWDetect.gpib) { return; } - TNT_4882_Status(3,0x04,1); + TNT_4882_Status(ESR,0x04,1); } void GPIB_Set_Device_Dependent_Error () { - if (!is_gpib) { + if (!globals.HWDetect.gpib) { return; } - TNT_4882_Status(3,0x08,1); + TNT_4882_Status(ESR,0x08,1); } @@ -1,5 +1,7 @@ /* define macros */ +#include <glib.h> + void GPIB_Set_Execution_Error(void); void GPIB_Set_Command_Error(void); void GPIB_Set_Query_Error(void); @@ -10,15 +12,15 @@ int GPIB_check_for_device_clear_signal(void); int GPIB_check_for_device_clear_signal(void); int GPIB_check_for_messages(char *gpib_buf); int GPIB_handle_new_input(char *gpib_buf); -int GPIB_send_query_response(char *out_buffer); +void GPIB_and_VXI_start_query_response(gpointer *ignore_this, char *in_string); +void GPIB_finish_query_response(); void GPIB_check_remote_status (int *is_remote, int *is_lockout); -unsigned char GPIB_response_already_pending (); void GPIB_go_to_local (); void GPIB_clear_events (); unsigned int GPIB_get_ESR (); unsigned int GPIB_get_SRE (); unsigned int GPIB_get_ESE (); -unsigned int GPIB_get_STB (); +unsigned int GPIB_and_VXI_get_STB (); void GPIB_set_ESR (unsigned int byte,int operation); void GPIB_set_SRE (unsigned int byte,int operation); void GPIB_set_ESE (unsigned int byte,int operation); diff --git a/instr-client.c b/instr-client.c index c894bee..990abc2 100644 --- a/instr-client.c +++ b/instr-client.c @@ -3,6 +3,9 @@ #include <string.h> #include <stdlib.h> #include <strings.h> +#include <sys/time.h> +#include <glib.h> +#include <glib/gprintf.h> #include "response.h" #include "version.h" @@ -45,6 +48,8 @@ static gboolean Matches(char *src, char* dst, gssize size) return TRUE; } +#define TIMEOUT 100000 // 100000 useconds, 100ms +#define ONESECONDINUSEC 1000000 //GIOChannel callback static gboolean @@ -57,6 +62,43 @@ stdinAvailable (GIOChannel *source, GIOCondition condition, gpointer data) return TRUE; } + // Ignore second \n if two are sent in rapid succession. + // This happens when the serial input is terminated with \r\n, + // which getty translates to \n\n. The IO handler splits this + // into 2 input lines, so we can't use a simple regex to + // replace it. + + static struct timeval last = { 0, 0 }; // the time this last ran + static struct timeval now; // the time now + gettimeofday(&now, NULL ); + + if (last.tv_sec != 0) { // shouldn't be zero if we have been in here before + if (strcmp(tmp, "\n") == 0) { // is this a newline all on it's own? + if (last.tv_sec == now.tv_sec) { + // if we're in the same second we can just check the usec field + if (now.tv_usec - last.tv_usec < TIMEOUT) { + // ignore this \n + return TRUE; + } + } + // - check that last and now sec fields are only one second apart + // - check that the time elapsed in this second is smaller than the + // timeout, if it isn't we don't need to check the other second + // - check that there is less of the last second remaining than the timeout + else if (now.tv_sec - last.tv_sec == 1 && now.tv_usec < TIMEOUT && (ONESECONDINUSEC - last.tv_usec) < TIMEOUT) { + // and then check the the time left in the last second + // plus the time in this second is less than the timeout + if ((ONESECONDINUSEC - last.tv_usec) + now.tv_usec < TIMEOUT) { + // ignore this \n + return TRUE; + } + } + } + } + + last = now; + + //test if we have an exit word int idx=0; for(idx=0; idx<sizeof(exitTokens)/sizeof(exitTokens[0]); idx++) { @@ -76,6 +118,7 @@ stdinAvailable (GIOChannel *source, GIOCondition condition, gpointer data) GError* error = NULL; written = g_pollable_output_stream_write_nonblocking(out, tmp, size, NULL, &error); + if(error != NULL && error->message) { g_print("Got error: %s\n", error->message); } @@ -132,7 +175,7 @@ int main(int argc, char** argv) g_object_unref(client); return -1; } - g_printf("Welcome to InstrumentShell v%s\n\n",FW_VERSION); + g_printf("\r\nWelcome! Avtech Electrosystems Ltd. - Firmware v%s\r\n\r\n",FW_VERSION); g_print("> "); //register Pollable sources 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; } @@ -210,6 +210,12 @@ void LCD_write_padded_spaces(int row, int col, char *LCD_string, int width) } +void LCD_write_padded_to_end_of_line(int row, int col, char *LCD_string) +{ + LCD_write_padded_spaces (row, col, LCD_string, LCD_cols - col); +} + + static void LCD_make_custom_chars() { /* define custom LCD characters 2 and 3 (up arrow and down arrow).*/ @@ -5,9 +5,6 @@ #define LCD_cols 40 #define LCD_rows 4 /* 4x40 LCD */ #define LCD_chars_total 160 - -/* LCD menu hardware definitions - FIXME */ - #define LCD_col_width 13 /* characters per LCD column */ #define LCD_max_entries_per_page 12 /* how many items fit on one LCD screen at a time */ #define LCD_max_entries 24 /* upper limit for menu arrays */ @@ -16,4 +13,5 @@ void LCD_display_extended_message(char *response, gboolean show_change_message, void LCD_clear(); void LCD_write(int row, int col, char *LCD_string); void LCD_write_padded_spaces(int row, int col, char *LCD_string, int width); +void LCD_write_padded_to_end_of_line(int row, int col, char *LCD_string); void LCD_initialize(void); diff --git a/libvxi11client/Makefile b/libvxi11client/Makefile new file mode 100644 index 0000000..b313b63 --- /dev/null +++ b/libvxi11client/Makefile @@ -0,0 +1,37 @@ +CFLAGS = -Wall -std=gnu99 `pkg-config --cflags gthread-2.0` +LFLAGS = `pkg-config --libs gthread-2.0` + +all: client + +client: libvxi11client.o vxi11_clnt.o vxi11_xdr.o client.o + $(CC) -o $@ $^ $(LFLAGS) + +client.o: client.c libvxi11client.h + $(CC) $(CFLAGS) -c $< + +libvxi11client.o: libvxi11client.c libvxi11client.h + $(CC) $(CFLAGS) -c $< + +vxi11_clnt.o: vxi11_clnt.c + $(CC) $(CFLAGS) -c $< + +vxi11_xdr.o: vxi11_xdr.c + $(CC) $(CFLAGS) -c $^ + +.PHONY: clean perl + +clean: + -rm *.o client + -rm -rf VXI11-Client + +perl: + -rm -rf VXI11-Client + h2xs -A -M vxi11 -x -n VXI11::Client libvxi11client.h + cp vxi11.h libvxi11client.c libvxi11client.h vxi11_clnt.c vxi11_xdr.c VXI11-Client/ + cp perlbits/Makefile.PL VXI11-Client/ + cp perlbits/VXI11-Client.t VXI11-Client/t/ + cp perlbits/typemap VXI11-Client/ + cd VXI11-Client/ && perl Makefile.PL + cd VXI11-Client/ && make + cd VXI11-Client/ && make test + diff --git a/libvxi11client/client.c b/libvxi11client/client.c new file mode 100644 index 0000000..04753a8 --- /dev/null +++ b/libvxi11client/client.c @@ -0,0 +1,162 @@ +#include <stdio.h> +#include <stdlib.h> +#include "libvxi11client.h" + +#define IDENTIFY "*IDN?" + +static char* geterrorstring(int errorcode) { + switch (errorcode) { + case 0: + return "invalid state (not connected) or no response from server"; + case -4: + return "invalid link identifier"; + case -6: + return "channel not established"; + case -8: + return "operation not supported"; + case -11: + return "device locked by another link"; + case -12: + return "no lock held by this link"; + case -29: + return "channel already established"; + default: + return "unknown error code"; + } +} + +int main(int argc, char *argv[]) { + + printf("VXI-11 test client\n"); + + if (argc != 2) { + printf("usage; %s <host>\n", argv[0]); + exit(1); + } + + int err = 0; + + if ((err = vxi11_open(argv[1], NULL)) > 0) { + + /** + * Basic tests + */ + + // write some bytes + int byteswritten = vxi11_write(IDENTIFY, sizeof(IDENTIFY), false); + if (byteswritten >= 0) + printf("Wrote %d bytes\n", byteswritten); + else + printf("Error writing data\n"); + + // read some bytes + int bytesread = vxi11_read(NULL, 0, false, false, 0); + if (bytesread >= 0) + printf("Read %d bytes\n", bytesread); + else + printf("Error reading data\n"); + + // trigger + if (vxi11_trigger(false) > 0) + printf("triggered\n"); + + // clear + if (vxi11_clear(false) > 0) + printf("cleared\n"); + + // abort + if ((err = vxi11_abort()) > 0) + printf("aborted\n"); + else + printf("abort failed; %s\n", geterrorstring(err)); + + // lock + if ((err = vxi11_lock(false)) > 0) + printf("locked\n"); + + // unlock + if ((err = vxi11_unlock()) > 0) + printf("unlocked\n"); + + // remote + if ((err = vxi11_remote(false)) > 0) + printf("remote'd\n"); + + // local + if ((err = vxi11_local(false)) > 0) + printf("local'd\n"); + + // read the status byte + int statusbyte = vxi11_readstatusbyte(false); + if (statusbyte >= 0) + printf("Status byte is 0x%02x\n", statusbyte); + else + printf("Error reading status byte\n"); + + /** + * Locking tests + */ + + // try locking twice + printf("-- Locking twice --\n"); + if ((err = vxi11_lock(false)) > 0) { + printf("locked\n"); + if ((err = vxi11_lock(false)) > 0) { + printf("locked again!!\n"); + exit(1); + } + else { + printf("Second lock failed; %s\n", geterrorstring(err)); + } + } + if ((err = vxi11_unlock()) > 0) + printf("unlocked\n"); + else { + printf("error unlocking; %s\n", geterrorstring(err)); + exit(1); + } + + printf("\n"); + + // try unlocking unlocked device + printf("-- Unlocking when unlocked --\n"); + if ((err = vxi11_unlock()) > 0) { + printf("Unlocked!!\n"); + exit(1); + } + else + printf("error unlocking; %s\n", geterrorstring(err)); + printf("\n"); + + // Interrupt channel tests + printf("-- Testing interrupt channel --\n"); + // create interrupt channel + if ((err = vxi11_create_intr_chan()) > 0) { + printf("Created interrupt channel\n"); + sleep(10); + // destroy interrupt channel + if ((err = vxi11_destroy_intr_chan()) > 0) + printf("Destroyed interrupt channel\n"); + else + printf("Error destroying interrupt channel; %s\n", geterrorstring(err)); + } + else + printf("Error creating interrupt channel; %s\n", geterrorstring(err)); + printf("\n"); + + // docmd + if ((err = vxi11_docmd(0x00, false)) > 0) + printf("did command, should fail!\n"); + else + printf("Error calling docmd; %s\n", geterrorstring(err)); + + // close + if ((err = vxi11_close() > 0)) + printf("Closed\n"); + } + else { + printf("Error opening device; %s\n", geterrorstring(err)); + exit(1); + } + return 0; +} diff --git a/libvxi11client/libvxi11client.c b/libvxi11client/libvxi11client.c new file mode 100644 index 0000000..2f36147 --- /dev/null +++ b/libvxi11client/libvxi11client.c @@ -0,0 +1,487 @@ +#include <stdbool.h> +#include <rpc/rpc.h> +#include <netinet/in.h> +#include <glib.h> +#include <poll.h> +#include "vxi11.h" + +#define DEBUG + +#ifdef DEBUG +#include <stdio.h> +#include <arpa/inet.h> +#endif + +/** + * This is a thin wrapper around the rpcgen generated code to give it a simpler interface. + * Only one server with a single link is supported. + */ + +#define FLAG_TERMCHRSET (1 << 7) +#define FLAG_END (1 << 3) +#define FLAG_WAITLOCK 1 + +#define VXI11_DEFAULT_TIMEOUT 1000 + +static CLIENT* clnt = NULL; +static CLIENT* abortclnt = NULL; +static Device_Link link; +static GThread* interruptthread; +static bool interruptchannelopen = false; + +static void killinterruptthreadandwait() { + interruptchannelopen = false; + g_thread_join(interruptthread); + interruptthread = NULL; +} + +void * +device_intr_srq_1_svc(Device_SrqParms *argp, struct svc_req *rqstp) { +#ifdef DEBUG + printf("device_intr_srq_1_svc()\n"); +#endif + static char * result; + return (void *) &result; +} + +static void device_intr_1(struct svc_req *rqstp, register SVCXPRT *transp) { + union { + Device_SrqParms device_intr_srq_1_arg; + } argument; + char *result; + xdrproc_t _xdr_argument, _xdr_result; + char *(*local)(char *, struct svc_req *); + + switch (rqstp->rq_proc) { + case NULLPROC: + (void) svc_sendreply(transp, (xdrproc_t) xdr_void, (char *) NULL); + return; + + case device_intr_srq: + _xdr_argument = (xdrproc_t) xdr_Device_SrqParms; + _xdr_result = (xdrproc_t) xdr_void; + local = (char *(*)(char *, struct svc_req *)) device_intr_srq_1_svc; + break; + + default: + svcerr_noproc(transp); + return; + } + memset((char *) &argument, 0, sizeof(argument)); + if (!svc_getargs(transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) { + svcerr_decode(transp); + return; + } + result = (*local)((char *) &argument, rqstp); + if (result != NULL && !svc_sendreply(transp, (xdrproc_t) _xdr_result, result)) { + svcerr_systemerr(transp); + } + if (!svc_freeargs(transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) { + fprintf(stderr, "%s", "unable to free arguments"); + exit(1); + } + return; +} + +static Device_Flags vxi11_generateflags(bool waitlock, bool end, bool termchrset) { + Device_Flags flags = 0; + if (waitlock) + flags |= FLAG_WAITLOCK; + if (end) + flags |= FLAG_END; + if (termchrset) + flags |= FLAG_TERMCHRSET; + return flags; +} + +/** + * create an RPC client and open a link to the server at $address. + * $device is apparently used for VXI-11 -> GPIB gateways.. this is untested. + */ + +int vxi11_open(char* address, char* device) { + clnt = clnt_create(address, DEVICE_CORE, DEVICE_CORE_VERSION, "tcp"); + + if (clnt == NULL) + return 0; + + else { + Create_LinkParms link_parms; + link_parms.clientId = (long) clnt; + link_parms.lockDevice = 0; + link_parms.lock_timeout = VXI11_DEFAULT_TIMEOUT; + link_parms.device = device != NULL ? device : "device0"; + + Create_LinkResp* linkresp = create_link_1(&link_parms, clnt); + if (linkresp != NULL && linkresp->error == 0) { + link = linkresp->lid; + +#ifdef DEBUG + printf("Link created, lid is %d, abort channel port %d\n", linkresp->lid, linkresp->abortPort); +#endif + + struct sockaddr_in serveraddr; + if (clnt_control(clnt, CLGET_SERVER_ADDR, (char*) &serveraddr)) { +#ifdef DEBUG + char addressstring[INET_ADDRSTRLEN]; + inet_ntop(AF_INET, &serveraddr.sin_addr, addressstring, sizeof(addressstring)); + printf("Remote is %s\n", addressstring); +#endif + serveraddr.sin_port = htons(linkresp->abortPort); + int sock = RPC_ANYSOCK; + abortclnt = clnttcp_create(&serveraddr, DEVICE_ASYNC, DEVICE_ASYNC_VERSION, &sock, 0, 0); + if (abortclnt == NULL) + return 0; + + } + else + // failed! + return 0; + + return 1; + } + else if (linkresp == NULL) + return 0; + else + return -(linkresp->error); + } +} + +/** + * read the status byte of the connected server + */ + +int vxi11_readstatusbyte(bool waitforlock) { + if (clnt == NULL) + return 0; + + Device_GenericParms params = { .lid = link, .flags = vxi11_generateflags(waitforlock, false, false), .lock_timeout = + VXI11_DEFAULT_TIMEOUT, .io_timeout = VXI11_DEFAULT_TIMEOUT }; + Device_ReadStbResp* resp = device_readstb_1(¶ms, clnt); + + if (resp != NULL && resp->error == 0) + return resp->stb; + else if (resp == NULL) + return 0; + else + return -1; +} + +/** + * write to the connected device + */ + +int vxi11_write(char* data, unsigned int len, bool waitlock, bool end) { + if (clnt == NULL) + return 0; + + Device_WriteParms params = { .lid = link, .io_timeout = VXI11_DEFAULT_TIMEOUT, + .lock_timeout = VXI11_DEFAULT_TIMEOUT, .flags = vxi11_generateflags(waitlock, end, false) }; + params.data.data_len = len; + params.data.data_val = data; + + Device_WriteResp* resp = device_write_1(¶ms, clnt); + if (resp != NULL && resp->error == 0) + return resp->size; + else if (resp == NULL) + return 0; + else + return -1; +} + +/** + * read from the connected device + */ + +int vxi11_read(char* buffer, unsigned int bufferlen, bool waitlock, bool termchrset, char termchr) { + if (clnt == NULL) + return 0; + + Device_ReadParms params = { .lid = link, .requestSize = 256, .io_timeout = VXI11_DEFAULT_TIMEOUT, .lock_timeout = + VXI11_DEFAULT_TIMEOUT, .flags = vxi11_generateflags(waitlock, false, termchrset), .termChar = + termchrset ? termchr : 0 }; + + Device_ReadResp* resp = device_read_1(¶ms, clnt); + if (resp != NULL && resp->error == 0) + return resp->data.data_len; + else if (resp == NULL) + return 0; + else + return -1; +} + +/** + * + */ + +int vxi11_docmd(unsigned long cmd, bool waitforlock) { + if (clnt == NULL) + return 0; + + Device_DocmdParms params = + { .lid = link, .flags = vxi11_generateflags(waitforlock, false, false), .io_timeout = VXI11_DEFAULT_TIMEOUT, + .lock_timeout = VXI11_DEFAULT_TIMEOUT, .cmd = cmd, .network_order = 0, .datasize = 0 }; + + params.data_in.data_in_len = 0; + params.data_in.data_in_val = NULL; + + Device_DocmdResp* resp = device_docmd_1(¶ms, clnt); + if (resp != NULL && resp->error == 0) + return 1; + else if (resp == NULL) + return 0; + else + return -(resp->error); +} + +/** + * trigger the connected device + */ + +int vxi11_trigger(bool waitforlock) { + if (clnt == NULL) + return 0; + + Device_GenericParms params = { .lid = link, .flags = vxi11_generateflags(waitforlock, false, false), .lock_timeout = + VXI11_DEFAULT_TIMEOUT, .io_timeout = VXI11_DEFAULT_TIMEOUT }; + Device_Error* error = device_trigger_1(¶ms, clnt); + + if (error->error == 0) + return 1; + else + return -(error->error); +} + +/** + * clear the connected device + */ + +int vxi11_clear(bool waitforlock) { + if (clnt == NULL) + return 0; + Device_GenericParms params = { .lid = link, .flags = vxi11_generateflags(waitforlock, false, false), .lock_timeout = + VXI11_DEFAULT_TIMEOUT, .io_timeout = VXI11_DEFAULT_TIMEOUT }; + Device_Error* error = device_clear_1(¶ms, clnt); + if (error != NULL && error->error == 0) + return 1; + else if (error == NULL) + return 0; + else + return -(error->error); +} + +/** + * remote the connected device + */ + +int vxi11_remote(bool waitforlock) { + if (clnt == NULL) + return 0; + Device_GenericParms params = { .lid = link, .flags = vxi11_generateflags(waitforlock, false, false), .lock_timeout = + VXI11_DEFAULT_TIMEOUT, .io_timeout = VXI11_DEFAULT_TIMEOUT }; + Device_Error* error = device_remote_1(¶ms, clnt); + if (error != NULL && error->error == 0) + return 1; + else if (error == NULL) + return 0; + else + return -(error->error); +} + +/** + * local the connected device + */ + +int vxi11_local(bool waitforlock) { + if (clnt == NULL) + return 0; + Device_GenericParms params = { .lid = link, .flags = vxi11_generateflags(waitforlock, false, false), .lock_timeout = + VXI11_DEFAULT_TIMEOUT, .io_timeout = VXI11_DEFAULT_TIMEOUT }; + Device_Error* error = device_local_1(¶ms, clnt); + if (error != NULL && error->error == 0) + return 1; + else if (error == NULL) + return 0; + else + return -(error->error); +} + +/** + * lock the connected device + */ + +int vxi11_lock(bool waitforlock) { + if (clnt == NULL) + return 0; + Device_LockParms params = { .lid = link, .flags = vxi11_generateflags(waitforlock, false, false), .lock_timeout = + VXI11_DEFAULT_TIMEOUT }; + Device_Error* error = device_lock_1(¶ms, clnt); + if (error != NULL && error->error == 0) + return 1; + else if (error == NULL) + return 0; + else + return -(error->error); +} + +/** + * unlock the connected device + */ + +int vxi11_unlock() { + if (clnt == NULL) + return 0; + Device_Error* error = device_unlock_1(&link, clnt); + if (error != NULL && error->error == 0) + return 1; + else if (error == NULL) + return 0; + else + return -(error->error); +} + +static gpointer interruptthreadfunc(gpointer data) { +#ifdef DEBUG + printf("Interrupt channel thread started\n"); +#endif + SVCXPRT *transp; + transp = svctcp_create(RPC_ANYSOCK, 0, 0); + if (transp == NULL) { + fprintf(stderr, "%s", "cannot create tcp service."); + return 0; + } + +#ifdef DEBUG + printf("Interrupt channel on port %d tcp\n", transp->xp_port); +#endif + + if (!svc_register(transp, DEVICE_INTR, DEVICE_INTR_VERSION, device_intr_1, 0)) { + fprintf(stderr, "%s", "unable to register (DEVICE_INTR, DEVICE_INTR_VERSION, tcp).\n"); + return 0; + } + *((unsigned int*) data) = transp->xp_port; + + int no_of_fds; + int i; + struct pollfd pollfd_set[1024]; + + //svc_run(); + // stolen from: http://pic.dhe.ibm.com/infocenter/aix/v6r1/index.jsp?topic=%2Fcom.ibm.aix.commtechref%2Fdoc%2Fcommtrf1%2Fsvc_getreq_poll.htm + while (interruptchannelopen) { + /* initialize the pollfd_set array and + get no of file descriptors in "no_of_fds"*/ + + /* Keep polling on file descriptors */ + switch (i = poll(pollfd_set, no_of_fds, -1)) { + case -1: + case 0: + continue; + default: + /* Handle RPC request on each file descriptor */ + svc_getreq_poll(pollfd_set, i); + } + } + +#ifdef DEBUG + printf("Interrupt channel thread ended\n"); +#endif + return NULL; +} + +/** + * create an interrupt channel from the connected device + */ +int vxi11_create_intr_chan() { + if (interruptchannelopen) + return 0; + else if (clnt == NULL) + return 0; + else if (interruptthread != NULL) + return 0; + + interruptchannelopen = true; + unsigned int port = -1; + g_thread_init(NULL); + interruptthread = g_thread_create(interruptthreadfunc, &port, true, NULL); + + while (port == -1) { // spin + }; + + struct sockaddr_in myaddress; + get_myaddress(&myaddress); + + Device_RemoteFunc remotefunc = { .hostAddr = myaddress.sin_addr.s_addr, .hostPort = port, .progNum = DEVICE_INTR, + .progVers = DEVICE_INTR_VERSION, .progFamily = DEVICE_TCP }; + Device_Error* error = create_intr_chan_1(&remotefunc, clnt); + if (error != NULL && error->error == 0) + return 1; + else if (error == NULL) { + killinterruptthreadandwait(); + return 0; + } + else { + killinterruptthreadandwait(); + return -(error->error); + } +} + +/** + * destroy an interrupt channel from the connected device + */ + +int vxi11_destroy_intr_chan() { + if (!interruptchannelopen) + return 0; + else if (clnt == NULL) + return 0; + else if (interruptthread == NULL) + return 0; + + Device_Error* error = destroy_intr_chan_1(NULL, clnt); + if (error != NULL && error->error == 0) { + killinterruptthreadandwait(); + return 1; + } + else if (error == NULL) + return 0; + else + return -(error->error); +} + +/** + * send an abort to the connected device + */ + +int vxi11_abort() { + if (abortclnt == NULL) + return 0; + Device_Error* error = device_abort_1(&link, abortclnt); + if (error != NULL && error->error == 0) + return 1; + else if (error == NULL) + return 0; + else + return -(error->error); +} + +/** + * close the current link and free the RPC client + */ + +int vxi11_close() { + if (clnt == NULL) + return 0; + + Device_Error* error = destroy_link_1(&link, clnt); + clnt_destroy(clnt); + clnt = NULL; + clnt_destroy(abortclnt); + abortclnt = NULL; + + if (error != NULL && error->error == 0) + return 1; + else if (error == NULL) + return 0; + else + return -(error->error); +} diff --git a/libvxi11client/libvxi11client.h b/libvxi11client/libvxi11client.h new file mode 100644 index 0000000..c9779e4 --- /dev/null +++ b/libvxi11client/libvxi11client.h @@ -0,0 +1,32 @@ +#include <stdbool.h> + +#define ERR_SYNTAXERROR -1 +#define ERR_DEVICENOTACCESSIBLE -3 +#define ERR_INVALIDLINKINDENTIFIER -4 +#define ERR_PARAMETERERROR -5 +#define ERR_CHANNELNOTESTABLISHED -6 +#define ERR_OPERATIONNOTSUPPORTED -8 +#define ERR_OUTOFRESOURCES -9 +#define ERR_DEVICELOCKEDBYANOTHERLINK -11 +#define ERR_NOLOCKHELDBYTHISLINK -12 +#define ERR_IOTIMEOUT -15 +#define ERR_IOERROR -17 +#define ERR_INVALIDADDRESS -21 +#define ERR_ABORT -23 +#define ERR_CHANNELALREADYESTABLISHED -29 + +int vxi11_open(char* address, char* device); +int vxi11_abort(void); +int vxi11_trigger(bool waitforlock); +int vxi11_clear(bool waitforlock); +int vxi11_write(char* data, unsigned int len, bool end); +int vxi11_read(char* buffer, unsigned int bufferlen, bool waitlock, bool termchrset, char termchr); +int vxi11_lock(bool waitforlock); +int vxi11_unlock(void); +int vxi11_local(bool waitforlock); +int vxi11_remote(bool waitforlock); +int vxi11_readstatusbyte(bool waitforlock); +int vxi11_create_intr_chan(void); +int vxi11_destroy_intr_chan(void); +int vxi11_docmd(unsigned long cmd, bool waitforlock); +int vxi11_close(void); diff --git a/libvxi11client/perlbits/Makefile.PL b/libvxi11client/perlbits/Makefile.PL new file mode 100644 index 0000000..801c91f --- /dev/null +++ b/libvxi11client/perlbits/Makefile.PL @@ -0,0 +1,39 @@ +use 5.014002; +use ExtUtils::MakeMaker; +# See lib/ExtUtils/MakeMaker.pm for details of how to influence +# the contents of the Makefile that is written. +WriteMakefile( + NAME => 'VXI11::Client', + VERSION_FROM => 'lib/VXI11/Client.pm', # finds $VERSION + PREREQ_PM => {}, # e.g., Module::Name => 1.1 + ($] >= 5.005 ? ## Add these new keywords supported since 5.005 + (ABSTRACT_FROM => 'lib/VXI11/Client.pm', # retrieve abstract from module + AUTHOR => 'daniel <daniel@>') : ()), + LIBS => [''], # e.g., '-lm' + DEFINE => '', # e.g., '-DHAVE_SOMETHING' + INC => '-I.', # e.g., '-I. -I/usr/include/other' + OBJECT => '$(O_FILES)', # link all the C files too +); +if (eval {require ExtUtils::Constant; 1}) { + # If you edit these definitions to change the constants used by this module, + # you will need to use the generated const-c.inc and const-xs.inc + # files to replace their "fallback" counterparts before distributing your + # changes. + my @names = (qw()); + ExtUtils::Constant::WriteConstants( + NAME => 'VXI11::Client', + NAMES => \@names, + DEFAULT_TYPE => 'IV', + C_FILE => 'const-c.inc', + XS_FILE => 'const-xs.inc', + ); + +} +else { + use File::Copy; + use File::Spec; + foreach my $file ('const-c.inc', 'const-xs.inc') { + my $fallback = File::Spec->catfile('fallback', $file); + copy ($fallback, $file) or die "Can't copy $fallback to $file: $!"; + } +} diff --git a/libvxi11client/perlbits/VXI11-Client.t b/libvxi11client/perlbits/VXI11-Client.t new file mode 100644 index 0000000..de10ecf --- /dev/null +++ b/libvxi11client/perlbits/VXI11-Client.t @@ -0,0 +1,22 @@ +# Before `make install' is performed this script should be runnable with +# `make test'. After `make install' it should work as `perl VXI11-Client.t' + +######################### + +# change 'tests => 1' to 'tests => last_test_to_print'; + +use strict; +use warnings; + +use Test::More tests => 5; +BEGIN { use_ok('VXI11::Client') }; + +######################### + +# Insert your test code below, the Test::More module is use()ed here so read +# its man page ( perldoc Test::More ) for help writing this test script. + +is(&VXI11::Client::vxi11_open("roi", 0), 1); +is(&VXI11::Client::vxi11_lock(0), 1); +is(&VXI11::Client::vxi11_unlock(), 1); +is(&VXI11::Client::vxi11_close(), 1); diff --git a/libvxi11client/perlbits/typemap b/libvxi11client/perlbits/typemap new file mode 100644 index 0000000..4391935 --- /dev/null +++ b/libvxi11client/perlbits/typemap @@ -0,0 +1 @@ +_Bool T_IV diff --git a/libvxi11client/vxi11.h b/libvxi11client/vxi11.h new file mode 100644 index 0000000..c21d661 --- /dev/null +++ b/libvxi11client/vxi11.h @@ -0,0 +1,342 @@ +/* + * Please do not edit this file. + * It was generated using rpcgen. + */ + +#ifndef _VXI11_H_RPCGEN +#define _VXI11_H_RPCGEN + +#include <rpc/rpc.h> + + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef long Device_Link; + +enum Device_AddrFamily { + DEVICE_TCP = 0, + DEVICE_UDP = 1, +}; +typedef enum Device_AddrFamily Device_AddrFamily; + +typedef long Device_Flags; + +typedef long Device_ErrorCode; + +struct Device_Error { + Device_ErrorCode error; +}; +typedef struct Device_Error Device_Error; + +struct Create_LinkParms { + long clientId; + bool_t lockDevice; + u_long lock_timeout; + char *device; +}; +typedef struct Create_LinkParms Create_LinkParms; + +struct Create_LinkResp { + Device_ErrorCode error; + Device_Link lid; + u_short abortPort; + u_long maxRecvSize; +}; +typedef struct Create_LinkResp Create_LinkResp; + +struct Device_WriteParms { + Device_Link lid; + u_long io_timeout; + u_long lock_timeout; + Device_Flags flags; + struct { + u_int data_len; + char *data_val; + } data; +}; +typedef struct Device_WriteParms Device_WriteParms; + +struct Device_WriteResp { + Device_ErrorCode error; + u_long size; +}; +typedef struct Device_WriteResp Device_WriteResp; + +struct Device_ReadParms { + Device_Link lid; + u_long requestSize; + u_long io_timeout; + u_long lock_timeout; + Device_Flags flags; + char termChar; +}; +typedef struct Device_ReadParms Device_ReadParms; + +struct Device_ReadResp { + Device_ErrorCode error; + long reason; + struct { + u_int data_len; + char *data_val; + } data; +}; +typedef struct Device_ReadResp Device_ReadResp; + +struct Device_ReadStbResp { + Device_ErrorCode error; + u_char stb; +}; +typedef struct Device_ReadStbResp Device_ReadStbResp; + +struct Device_GenericParms { + Device_Link lid; + Device_Flags flags; + u_long lock_timeout; + u_long io_timeout; +}; +typedef struct Device_GenericParms Device_GenericParms; + +struct Device_RemoteFunc { + u_long hostAddr; + u_long hostPort; + u_long progNum; + u_long progVers; + Device_AddrFamily progFamily; +}; +typedef struct Device_RemoteFunc Device_RemoteFunc; + +struct Device_EnableSrqParms { + Device_Link lid; + bool_t enable; + struct { + u_int handle_len; + char *handle_val; + } handle; +}; +typedef struct Device_EnableSrqParms Device_EnableSrqParms; + +struct Device_LockParms { + Device_Link lid; + Device_Flags flags; + u_long lock_timeout; +}; +typedef struct Device_LockParms Device_LockParms; + +struct Device_DocmdParms { + Device_Link lid; + Device_Flags flags; + u_long io_timeout; + u_long lock_timeout; + long cmd; + bool_t network_order; + long datasize; + struct { + u_int data_in_len; + char *data_in_val; + } data_in; +}; +typedef struct Device_DocmdParms Device_DocmdParms; + +struct Device_DocmdResp { + Device_ErrorCode error; + struct { + u_int data_out_len; + char *data_out_val; + } data_out; +}; +typedef struct Device_DocmdResp Device_DocmdResp; + +struct Device_SrqParms { + struct { + u_int handle_len; + char *handle_val; + } handle; +}; +typedef struct Device_SrqParms Device_SrqParms; + +#define DEVICE_ASYNC 0x0607B0 +#define DEVICE_ASYNC_VERSION 1 + +#if defined(__STDC__) || defined(__cplusplus) +#define device_abort 1 +extern Device_Error * device_abort_1(Device_Link *, CLIENT *); +extern Device_Error * device_abort_1_svc(Device_Link *, struct svc_req *); +extern int device_async_1_freeresult (SVCXPRT *, xdrproc_t, caddr_t); + +#else /* K&R C */ +#define device_abort 1 +extern Device_Error * device_abort_1(); +extern Device_Error * device_abort_1_svc(); +extern int device_async_1_freeresult (); +#endif /* K&R C */ + +#define DEVICE_CORE 0x0607AF +#define DEVICE_CORE_VERSION 1 + +#if defined(__STDC__) || defined(__cplusplus) +#define create_link 10 +extern Create_LinkResp * create_link_1(Create_LinkParms *, CLIENT *); +extern Create_LinkResp * create_link_1_svc(Create_LinkParms *, struct svc_req *); +#define device_write 11 +extern Device_WriteResp * device_write_1(Device_WriteParms *, CLIENT *); +extern Device_WriteResp * device_write_1_svc(Device_WriteParms *, struct svc_req *); +#define device_read 12 +extern Device_ReadResp * device_read_1(Device_ReadParms *, CLIENT *); +extern Device_ReadResp * device_read_1_svc(Device_ReadParms *, struct svc_req *); +#define device_readstb 13 +extern Device_ReadStbResp * device_readstb_1(Device_GenericParms *, CLIENT *); +extern Device_ReadStbResp * device_readstb_1_svc(Device_GenericParms *, struct svc_req *); +#define device_trigger 14 +extern Device_Error * device_trigger_1(Device_GenericParms *, CLIENT *); +extern Device_Error * device_trigger_1_svc(Device_GenericParms *, struct svc_req *); +#define device_clear 15 +extern Device_Error * device_clear_1(Device_GenericParms *, CLIENT *); +extern Device_Error * device_clear_1_svc(Device_GenericParms *, struct svc_req *); +#define device_remote 16 +extern Device_Error * device_remote_1(Device_GenericParms *, CLIENT *); +extern Device_Error * device_remote_1_svc(Device_GenericParms *, struct svc_req *); +#define device_local 17 +extern Device_Error * device_local_1(Device_GenericParms *, CLIENT *); +extern Device_Error * device_local_1_svc(Device_GenericParms *, struct svc_req *); +#define device_lock 18 +extern Device_Error * device_lock_1(Device_LockParms *, CLIENT *); +extern Device_Error * device_lock_1_svc(Device_LockParms *, struct svc_req *); +#define device_unlock 19 +extern Device_Error * device_unlock_1(Device_Link *, CLIENT *); +extern Device_Error * device_unlock_1_svc(Device_Link *, struct svc_req *); +#define device_enable_srq 20 +extern Device_Error * device_enable_srq_1(Device_EnableSrqParms *, CLIENT *); +extern Device_Error * device_enable_srq_1_svc(Device_EnableSrqParms *, struct svc_req *); +#define device_docmd 22 +extern Device_DocmdResp * device_docmd_1(Device_DocmdParms *, CLIENT *); +extern Device_DocmdResp * device_docmd_1_svc(Device_DocmdParms *, struct svc_req *); +#define destroy_link 23 +extern Device_Error * destroy_link_1(Device_Link *, CLIENT *); +extern Device_Error * destroy_link_1_svc(Device_Link *, struct svc_req *); +#define create_intr_chan 25 +extern Device_Error * create_intr_chan_1(Device_RemoteFunc *, CLIENT *); +extern Device_Error * create_intr_chan_1_svc(Device_RemoteFunc *, struct svc_req *); +#define destroy_intr_chan 26 +extern Device_Error * destroy_intr_chan_1(void *, CLIENT *); +extern Device_Error * destroy_intr_chan_1_svc(void *, struct svc_req *); +extern int device_core_1_freeresult (SVCXPRT *, xdrproc_t, caddr_t); + +#else /* K&R C */ +#define create_link 10 +extern Create_LinkResp * create_link_1(); +extern Create_LinkResp * create_link_1_svc(); +#define device_write 11 +extern Device_WriteResp * device_write_1(); +extern Device_WriteResp * device_write_1_svc(); +#define device_read 12 +extern Device_ReadResp * device_read_1(); +extern Device_ReadResp * device_read_1_svc(); +#define device_readstb 13 +extern Device_ReadStbResp * device_readstb_1(); +extern Device_ReadStbResp * device_readstb_1_svc(); +#define device_trigger 14 +extern Device_Error * device_trigger_1(); +extern Device_Error * device_trigger_1_svc(); +#define device_clear 15 +extern Device_Error * device_clear_1(); +extern Device_Error * device_clear_1_svc(); +#define device_remote 16 +extern Device_Error * device_remote_1(); +extern Device_Error * device_remote_1_svc(); +#define device_local 17 +extern Device_Error * device_local_1(); +extern Device_Error * device_local_1_svc(); +#define device_lock 18 +extern Device_Error * device_lock_1(); +extern Device_Error * device_lock_1_svc(); +#define device_unlock 19 +extern Device_Error * device_unlock_1(); +extern Device_Error * device_unlock_1_svc(); +#define device_enable_srq 20 +extern Device_Error * device_enable_srq_1(); +extern Device_Error * device_enable_srq_1_svc(); +#define device_docmd 22 +extern Device_DocmdResp * device_docmd_1(); +extern Device_DocmdResp * device_docmd_1_svc(); +#define destroy_link 23 +extern Device_Error * destroy_link_1(); +extern Device_Error * destroy_link_1_svc(); +#define create_intr_chan 25 +extern Device_Error * create_intr_chan_1(); +extern Device_Error * create_intr_chan_1_svc(); +#define destroy_intr_chan 26 +extern Device_Error * destroy_intr_chan_1(); +extern Device_Error * destroy_intr_chan_1_svc(); +extern int device_core_1_freeresult (); +#endif /* K&R C */ + +#define DEVICE_INTR 0x0607B1 +#define DEVICE_INTR_VERSION 1 + +#if defined(__STDC__) || defined(__cplusplus) +#define device_intr_srq 30 +extern void * device_intr_srq_1(Device_SrqParms *, CLIENT *); +extern void * device_intr_srq_1_svc(Device_SrqParms *, struct svc_req *); +extern int device_intr_1_freeresult (SVCXPRT *, xdrproc_t, caddr_t); + +#else /* K&R C */ +#define device_intr_srq 30 +extern void * device_intr_srq_1(); +extern void * device_intr_srq_1_svc(); +extern int device_intr_1_freeresult (); +#endif /* K&R C */ + +/* the xdr functions */ + +#if defined(__STDC__) || defined(__cplusplus) +extern bool_t xdr_Device_Link (XDR *, Device_Link*); +extern bool_t xdr_Device_AddrFamily (XDR *, Device_AddrFamily*); +extern bool_t xdr_Device_Flags (XDR *, Device_Flags*); +extern bool_t xdr_Device_ErrorCode (XDR *, Device_ErrorCode*); +extern bool_t xdr_Device_Error (XDR *, Device_Error*); +extern bool_t xdr_Create_LinkParms (XDR *, Create_LinkParms*); +extern bool_t xdr_Create_LinkResp (XDR *, Create_LinkResp*); +extern bool_t xdr_Device_WriteParms (XDR *, Device_WriteParms*); +extern bool_t xdr_Device_WriteResp (XDR *, Device_WriteResp*); +extern bool_t xdr_Device_ReadParms (XDR *, Device_ReadParms*); +extern bool_t xdr_Device_ReadResp (XDR *, Device_ReadResp*); +extern bool_t xdr_Device_ReadStbResp (XDR *, Device_ReadStbResp*); +extern bool_t xdr_Device_GenericParms (XDR *, Device_GenericParms*); +extern bool_t xdr_Device_RemoteFunc (XDR *, Device_RemoteFunc*); +extern bool_t xdr_Device_EnableSrqParms (XDR *, Device_EnableSrqParms*); +extern bool_t xdr_Device_LockParms (XDR *, Device_LockParms*); +extern bool_t xdr_Device_DocmdParms (XDR *, Device_DocmdParms*); +extern bool_t xdr_Device_DocmdResp (XDR *, Device_DocmdResp*); +extern bool_t xdr_Device_SrqParms (XDR *, Device_SrqParms*); + +#else /* K&R C */ +extern bool_t xdr_Device_Link (); +extern bool_t xdr_Device_AddrFamily (); +extern bool_t xdr_Device_Flags (); +extern bool_t xdr_Device_ErrorCode (); +extern bool_t xdr_Device_Error (); +extern bool_t xdr_Create_LinkParms (); +extern bool_t xdr_Create_LinkResp (); +extern bool_t xdr_Device_WriteParms (); +extern bool_t xdr_Device_WriteResp (); +extern bool_t xdr_Device_ReadParms (); +extern bool_t xdr_Device_ReadResp (); +extern bool_t xdr_Device_ReadStbResp (); +extern bool_t xdr_Device_GenericParms (); +extern bool_t xdr_Device_RemoteFunc (); +extern bool_t xdr_Device_EnableSrqParms (); +extern bool_t xdr_Device_LockParms (); +extern bool_t xdr_Device_DocmdParms (); +extern bool_t xdr_Device_DocmdResp (); +extern bool_t xdr_Device_SrqParms (); + +#endif /* K&R C */ + +#ifdef __cplusplus +} +#endif + +#endif /* !_VXI11_H_RPCGEN */ diff --git a/libvxi11client/vxi11_clnt.c b/libvxi11client/vxi11_clnt.c new file mode 100644 index 0000000..d8f339a --- /dev/null +++ b/libvxi11client/vxi11_clnt.c @@ -0,0 +1,265 @@ +/* + * Please do not edit this file. + * It was generated using rpcgen. + */ + +#include <memory.h> /* for memset */ +#include "vxi11.h" + +/* Default timeout can be changed using clnt_control() */ +static struct timeval TIMEOUT = { 25, 0 }; + +Device_Error * +device_abort_1(Device_Link *argp, CLIENT *clnt) +{ + static Device_Error clnt_res; + + memset((char *)&clnt_res, 0, sizeof(clnt_res)); + if (clnt_call (clnt, device_abort, + (xdrproc_t) xdr_Device_Link, (caddr_t) argp, + (xdrproc_t) xdr_Device_Error, (caddr_t) &clnt_res, + TIMEOUT) != RPC_SUCCESS) { + return (NULL); + } + return (&clnt_res); +} + +Create_LinkResp * +create_link_1(Create_LinkParms *argp, CLIENT *clnt) +{ + static Create_LinkResp clnt_res; + + memset((char *)&clnt_res, 0, sizeof(clnt_res)); + if (clnt_call (clnt, create_link, + (xdrproc_t) xdr_Create_LinkParms, (caddr_t) argp, + (xdrproc_t) xdr_Create_LinkResp, (caddr_t) &clnt_res, + TIMEOUT) != RPC_SUCCESS) { + return (NULL); + } + return (&clnt_res); +} + +Device_WriteResp * +device_write_1(Device_WriteParms *argp, CLIENT *clnt) +{ + static Device_WriteResp clnt_res; + + memset((char *)&clnt_res, 0, sizeof(clnt_res)); + if (clnt_call (clnt, device_write, + (xdrproc_t) xdr_Device_WriteParms, (caddr_t) argp, + (xdrproc_t) xdr_Device_WriteResp, (caddr_t) &clnt_res, + TIMEOUT) != RPC_SUCCESS) { + return (NULL); + } + return (&clnt_res); +} + +Device_ReadResp * +device_read_1(Device_ReadParms *argp, CLIENT *clnt) +{ + static Device_ReadResp clnt_res; + + memset((char *)&clnt_res, 0, sizeof(clnt_res)); + if (clnt_call (clnt, device_read, + (xdrproc_t) xdr_Device_ReadParms, (caddr_t) argp, + (xdrproc_t) xdr_Device_ReadResp, (caddr_t) &clnt_res, + TIMEOUT) != RPC_SUCCESS) { + return (NULL); + } + return (&clnt_res); +} + +Device_ReadStbResp * +device_readstb_1(Device_GenericParms *argp, CLIENT *clnt) +{ + static Device_ReadStbResp clnt_res; + + memset((char *)&clnt_res, 0, sizeof(clnt_res)); + if (clnt_call (clnt, device_readstb, + (xdrproc_t) xdr_Device_GenericParms, (caddr_t) argp, + (xdrproc_t) xdr_Device_ReadStbResp, (caddr_t) &clnt_res, + TIMEOUT) != RPC_SUCCESS) { + return (NULL); + } + return (&clnt_res); +} + +Device_Error * +device_trigger_1(Device_GenericParms *argp, CLIENT *clnt) +{ + static Device_Error clnt_res; + + memset((char *)&clnt_res, 0, sizeof(clnt_res)); + if (clnt_call (clnt, device_trigger, + (xdrproc_t) xdr_Device_GenericParms, (caddr_t) argp, + (xdrproc_t) xdr_Device_Error, (caddr_t) &clnt_res, + TIMEOUT) != RPC_SUCCESS) { + return (NULL); + } + return (&clnt_res); +} + +Device_Error * +device_clear_1(Device_GenericParms *argp, CLIENT *clnt) +{ + static Device_Error clnt_res; + + memset((char *)&clnt_res, 0, sizeof(clnt_res)); + if (clnt_call (clnt, device_clear, + (xdrproc_t) xdr_Device_GenericParms, (caddr_t) argp, + (xdrproc_t) xdr_Device_Error, (caddr_t) &clnt_res, + TIMEOUT) != RPC_SUCCESS) { + return (NULL); + } + return (&clnt_res); +} + +Device_Error * +device_remote_1(Device_GenericParms *argp, CLIENT *clnt) +{ + static Device_Error clnt_res; + + memset((char *)&clnt_res, 0, sizeof(clnt_res)); + if (clnt_call (clnt, device_remote, + (xdrproc_t) xdr_Device_GenericParms, (caddr_t) argp, + (xdrproc_t) xdr_Device_Error, (caddr_t) &clnt_res, + TIMEOUT) != RPC_SUCCESS) { + return (NULL); + } + return (&clnt_res); +} + +Device_Error * +device_local_1(Device_GenericParms *argp, CLIENT *clnt) +{ + static Device_Error clnt_res; + + memset((char *)&clnt_res, 0, sizeof(clnt_res)); + if (clnt_call (clnt, device_local, + (xdrproc_t) xdr_Device_GenericParms, (caddr_t) argp, + (xdrproc_t) xdr_Device_Error, (caddr_t) &clnt_res, + TIMEOUT) != RPC_SUCCESS) { + return (NULL); + } + return (&clnt_res); +} + +Device_Error * +device_lock_1(Device_LockParms *argp, CLIENT *clnt) +{ + static Device_Error clnt_res; + + memset((char *)&clnt_res, 0, sizeof(clnt_res)); + if (clnt_call (clnt, device_lock, + (xdrproc_t) xdr_Device_LockParms, (caddr_t) argp, + (xdrproc_t) xdr_Device_Error, (caddr_t) &clnt_res, + TIMEOUT) != RPC_SUCCESS) { + return (NULL); + } + return (&clnt_res); +} + +Device_Error * +device_unlock_1(Device_Link *argp, CLIENT *clnt) +{ + static Device_Error clnt_res; + + memset((char *)&clnt_res, 0, sizeof(clnt_res)); + if (clnt_call (clnt, device_unlock, + (xdrproc_t) xdr_Device_Link, (caddr_t) argp, + (xdrproc_t) xdr_Device_Error, (caddr_t) &clnt_res, + TIMEOUT) != RPC_SUCCESS) { + return (NULL); + } + return (&clnt_res); +} + +Device_Error * +device_enable_srq_1(Device_EnableSrqParms *argp, CLIENT *clnt) +{ + static Device_Error clnt_res; + + memset((char *)&clnt_res, 0, sizeof(clnt_res)); + if (clnt_call (clnt, device_enable_srq, + (xdrproc_t) xdr_Device_EnableSrqParms, (caddr_t) argp, + (xdrproc_t) xdr_Device_Error, (caddr_t) &clnt_res, + TIMEOUT) != RPC_SUCCESS) { + return (NULL); + } + return (&clnt_res); +} + +Device_DocmdResp * +device_docmd_1(Device_DocmdParms *argp, CLIENT *clnt) +{ + static Device_DocmdResp clnt_res; + + memset((char *)&clnt_res, 0, sizeof(clnt_res)); + if (clnt_call (clnt, device_docmd, + (xdrproc_t) xdr_Device_DocmdParms, (caddr_t) argp, + (xdrproc_t) xdr_Device_DocmdResp, (caddr_t) &clnt_res, + TIMEOUT) != RPC_SUCCESS) { + return (NULL); + } + return (&clnt_res); +} + +Device_Error * +destroy_link_1(Device_Link *argp, CLIENT *clnt) +{ + static Device_Error clnt_res; + + memset((char *)&clnt_res, 0, sizeof(clnt_res)); + if (clnt_call (clnt, destroy_link, + (xdrproc_t) xdr_Device_Link, (caddr_t) argp, + (xdrproc_t) xdr_Device_Error, (caddr_t) &clnt_res, + TIMEOUT) != RPC_SUCCESS) { + return (NULL); + } + return (&clnt_res); +} + +Device_Error * +create_intr_chan_1(Device_RemoteFunc *argp, CLIENT *clnt) +{ + static Device_Error clnt_res; + + memset((char *)&clnt_res, 0, sizeof(clnt_res)); + if (clnt_call (clnt, create_intr_chan, + (xdrproc_t) xdr_Device_RemoteFunc, (caddr_t) argp, + (xdrproc_t) xdr_Device_Error, (caddr_t) &clnt_res, + TIMEOUT) != RPC_SUCCESS) { + return (NULL); + } + return (&clnt_res); +} + +Device_Error * +destroy_intr_chan_1(void *argp, CLIENT *clnt) +{ + static Device_Error clnt_res; + + memset((char *)&clnt_res, 0, sizeof(clnt_res)); + if (clnt_call (clnt, destroy_intr_chan, + (xdrproc_t) xdr_void, (caddr_t) argp, + (xdrproc_t) xdr_Device_Error, (caddr_t) &clnt_res, + TIMEOUT) != RPC_SUCCESS) { + return (NULL); + } + return (&clnt_res); +} + +void * +device_intr_srq_1(Device_SrqParms *argp, CLIENT *clnt) +{ + static char clnt_res; + + memset((char *)&clnt_res, 0, sizeof(clnt_res)); + if (clnt_call (clnt, device_intr_srq, + (xdrproc_t) xdr_Device_SrqParms, (caddr_t) argp, + (xdrproc_t) xdr_void, (caddr_t) &clnt_res, + TIMEOUT) != RPC_SUCCESS) { + return (NULL); + } + return ((void *)&clnt_res); +} diff --git a/libvxi11client/vxi11_xdr.c b/libvxi11client/vxi11_xdr.c new file mode 100644 index 0000000..29d9371 --- /dev/null +++ b/libvxi11client/vxi11_xdr.c @@ -0,0 +1,462 @@ +/* + * Please do not edit this file. + * It was generated using rpcgen. + */ + +#include "vxi11.h" + +bool_t +xdr_Device_Link (XDR *xdrs, Device_Link *objp) +{ + register int32_t *buf; + + if (!xdr_long (xdrs, objp)) + return FALSE; + return TRUE; +} + +bool_t +xdr_Device_AddrFamily (XDR *xdrs, Device_AddrFamily *objp) +{ + register int32_t *buf; + + if (!xdr_enum (xdrs, (enum_t *) objp)) + return FALSE; + return TRUE; +} + +bool_t +xdr_Device_Flags (XDR *xdrs, Device_Flags *objp) +{ + register int32_t *buf; + + if (!xdr_long (xdrs, objp)) + return FALSE; + return TRUE; +} + +bool_t +xdr_Device_ErrorCode (XDR *xdrs, Device_ErrorCode *objp) +{ + register int32_t *buf; + + if (!xdr_long (xdrs, objp)) + return FALSE; + return TRUE; +} + +bool_t +xdr_Device_Error (XDR *xdrs, Device_Error *objp) +{ + register int32_t *buf; + + if (!xdr_Device_ErrorCode (xdrs, &objp->error)) + return FALSE; + return TRUE; +} + +bool_t +xdr_Create_LinkParms (XDR *xdrs, Create_LinkParms *objp) +{ + register int32_t *buf; + + + if (xdrs->x_op == XDR_ENCODE) { + buf = XDR_INLINE (xdrs, 3 * BYTES_PER_XDR_UNIT); + if (buf == NULL) { + if (!xdr_long (xdrs, &objp->clientId)) + return FALSE; + if (!xdr_bool (xdrs, &objp->lockDevice)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->lock_timeout)) + return FALSE; + + } else { + IXDR_PUT_LONG(buf, objp->clientId); + IXDR_PUT_BOOL(buf, objp->lockDevice); + IXDR_PUT_U_LONG(buf, objp->lock_timeout); + } + if (!xdr_string (xdrs, &objp->device, ~0)) + return FALSE; + return TRUE; + } else if (xdrs->x_op == XDR_DECODE) { + buf = XDR_INLINE (xdrs, 3 * BYTES_PER_XDR_UNIT); + if (buf == NULL) { + if (!xdr_long (xdrs, &objp->clientId)) + return FALSE; + if (!xdr_bool (xdrs, &objp->lockDevice)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->lock_timeout)) + return FALSE; + + } else { + objp->clientId = IXDR_GET_LONG(buf); + objp->lockDevice = IXDR_GET_BOOL(buf); + objp->lock_timeout = IXDR_GET_U_LONG(buf); + } + if (!xdr_string (xdrs, &objp->device, ~0)) + return FALSE; + return TRUE; + } + + if (!xdr_long (xdrs, &objp->clientId)) + return FALSE; + if (!xdr_bool (xdrs, &objp->lockDevice)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->lock_timeout)) + return FALSE; + if (!xdr_string (xdrs, &objp->device, ~0)) + return FALSE; + return TRUE; +} + +bool_t +xdr_Create_LinkResp (XDR *xdrs, Create_LinkResp *objp) +{ + register int32_t *buf; + + if (!xdr_Device_ErrorCode (xdrs, &objp->error)) + return FALSE; + if (!xdr_Device_Link (xdrs, &objp->lid)) + return FALSE; + if (!xdr_u_short (xdrs, &objp->abortPort)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->maxRecvSize)) + return FALSE; + return TRUE; +} + +bool_t +xdr_Device_WriteParms (XDR *xdrs, Device_WriteParms *objp) +{ + register int32_t *buf; + + if (!xdr_Device_Link (xdrs, &objp->lid)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->io_timeout)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->lock_timeout)) + return FALSE; + if (!xdr_Device_Flags (xdrs, &objp->flags)) + return FALSE; + if (!xdr_bytes (xdrs, (char **)&objp->data.data_val, (u_int *) &objp->data.data_len, ~0)) + return FALSE; + return TRUE; +} + +bool_t +xdr_Device_WriteResp (XDR *xdrs, Device_WriteResp *objp) +{ + register int32_t *buf; + + if (!xdr_Device_ErrorCode (xdrs, &objp->error)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->size)) + return FALSE; + return TRUE; +} + +bool_t +xdr_Device_ReadParms (XDR *xdrs, Device_ReadParms *objp) +{ + register int32_t *buf; + + + if (xdrs->x_op == XDR_ENCODE) { + if (!xdr_Device_Link (xdrs, &objp->lid)) + return FALSE; + buf = XDR_INLINE (xdrs, 3 * BYTES_PER_XDR_UNIT); + if (buf == NULL) { + if (!xdr_u_long (xdrs, &objp->requestSize)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->io_timeout)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->lock_timeout)) + return FALSE; + + } else { + IXDR_PUT_U_LONG(buf, objp->requestSize); + IXDR_PUT_U_LONG(buf, objp->io_timeout); + IXDR_PUT_U_LONG(buf, objp->lock_timeout); + } + if (!xdr_Device_Flags (xdrs, &objp->flags)) + return FALSE; + if (!xdr_char (xdrs, &objp->termChar)) + return FALSE; + return TRUE; + } else if (xdrs->x_op == XDR_DECODE) { + if (!xdr_Device_Link (xdrs, &objp->lid)) + return FALSE; + buf = XDR_INLINE (xdrs, 3 * BYTES_PER_XDR_UNIT); + if (buf == NULL) { + if (!xdr_u_long (xdrs, &objp->requestSize)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->io_timeout)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->lock_timeout)) + return FALSE; + + } else { + objp->requestSize = IXDR_GET_U_LONG(buf); + objp->io_timeout = IXDR_GET_U_LONG(buf); + objp->lock_timeout = IXDR_GET_U_LONG(buf); + } + if (!xdr_Device_Flags (xdrs, &objp->flags)) + return FALSE; + if (!xdr_char (xdrs, &objp->termChar)) + return FALSE; + return TRUE; + } + + if (!xdr_Device_Link (xdrs, &objp->lid)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->requestSize)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->io_timeout)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->lock_timeout)) + return FALSE; + if (!xdr_Device_Flags (xdrs, &objp->flags)) + return FALSE; + if (!xdr_char (xdrs, &objp->termChar)) + return FALSE; + return TRUE; +} + +bool_t +xdr_Device_ReadResp (XDR *xdrs, Device_ReadResp *objp) +{ + register int32_t *buf; + + if (!xdr_Device_ErrorCode (xdrs, &objp->error)) + return FALSE; + if (!xdr_long (xdrs, &objp->reason)) + return FALSE; + if (!xdr_bytes (xdrs, (char **)&objp->data.data_val, (u_int *) &objp->data.data_len, ~0)) + return FALSE; + return TRUE; +} + +bool_t +xdr_Device_ReadStbResp (XDR *xdrs, Device_ReadStbResp *objp) +{ + register int32_t *buf; + + if (!xdr_Device_ErrorCode (xdrs, &objp->error)) + return FALSE; + if (!xdr_u_char (xdrs, &objp->stb)) + return FALSE; + return TRUE; +} + +bool_t +xdr_Device_GenericParms (XDR *xdrs, Device_GenericParms *objp) +{ + register int32_t *buf; + + if (!xdr_Device_Link (xdrs, &objp->lid)) + return FALSE; + if (!xdr_Device_Flags (xdrs, &objp->flags)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->lock_timeout)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->io_timeout)) + return FALSE; + return TRUE; +} + +bool_t +xdr_Device_RemoteFunc (XDR *xdrs, Device_RemoteFunc *objp) +{ + register int32_t *buf; + + + if (xdrs->x_op == XDR_ENCODE) { + buf = XDR_INLINE (xdrs, 4 * BYTES_PER_XDR_UNIT); + if (buf == NULL) { + if (!xdr_u_long (xdrs, &objp->hostAddr)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->hostPort)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->progNum)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->progVers)) + return FALSE; + + } else { + IXDR_PUT_U_LONG(buf, objp->hostAddr); + IXDR_PUT_U_LONG(buf, objp->hostPort); + IXDR_PUT_U_LONG(buf, objp->progNum); + IXDR_PUT_U_LONG(buf, objp->progVers); + } + if (!xdr_Device_AddrFamily (xdrs, &objp->progFamily)) + return FALSE; + return TRUE; + } else if (xdrs->x_op == XDR_DECODE) { + buf = XDR_INLINE (xdrs, 4 * BYTES_PER_XDR_UNIT); + if (buf == NULL) { + if (!xdr_u_long (xdrs, &objp->hostAddr)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->hostPort)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->progNum)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->progVers)) + return FALSE; + + } else { + objp->hostAddr = IXDR_GET_U_LONG(buf); + objp->hostPort = IXDR_GET_U_LONG(buf); + objp->progNum = IXDR_GET_U_LONG(buf); + objp->progVers = IXDR_GET_U_LONG(buf); + } + if (!xdr_Device_AddrFamily (xdrs, &objp->progFamily)) + return FALSE; + return TRUE; + } + + if (!xdr_u_long (xdrs, &objp->hostAddr)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->hostPort)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->progNum)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->progVers)) + return FALSE; + if (!xdr_Device_AddrFamily (xdrs, &objp->progFamily)) + return FALSE; + return TRUE; +} + +bool_t +xdr_Device_EnableSrqParms (XDR *xdrs, Device_EnableSrqParms *objp) +{ + register int32_t *buf; + + if (!xdr_Device_Link (xdrs, &objp->lid)) + return FALSE; + if (!xdr_bool (xdrs, &objp->enable)) + return FALSE; + if (!xdr_bytes (xdrs, (char **)&objp->handle.handle_val, (u_int *) &objp->handle.handle_len, 40)) + return FALSE; + return TRUE; +} + +bool_t +xdr_Device_LockParms (XDR *xdrs, Device_LockParms *objp) +{ + register int32_t *buf; + + if (!xdr_Device_Link (xdrs, &objp->lid)) + return FALSE; + if (!xdr_Device_Flags (xdrs, &objp->flags)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->lock_timeout)) + return FALSE; + return TRUE; +} + +bool_t +xdr_Device_DocmdParms (XDR *xdrs, Device_DocmdParms *objp) +{ + register int32_t *buf; + + + if (xdrs->x_op == XDR_ENCODE) { + if (!xdr_Device_Link (xdrs, &objp->lid)) + return FALSE; + if (!xdr_Device_Flags (xdrs, &objp->flags)) + return FALSE; + buf = XDR_INLINE (xdrs, 5 * BYTES_PER_XDR_UNIT); + if (buf == NULL) { + if (!xdr_u_long (xdrs, &objp->io_timeout)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->lock_timeout)) + return FALSE; + if (!xdr_long (xdrs, &objp->cmd)) + return FALSE; + if (!xdr_bool (xdrs, &objp->network_order)) + return FALSE; + if (!xdr_long (xdrs, &objp->datasize)) + return FALSE; + + } else { + IXDR_PUT_U_LONG(buf, objp->io_timeout); + IXDR_PUT_U_LONG(buf, objp->lock_timeout); + IXDR_PUT_LONG(buf, objp->cmd); + IXDR_PUT_BOOL(buf, objp->network_order); + IXDR_PUT_LONG(buf, objp->datasize); + } + if (!xdr_bytes (xdrs, (char **)&objp->data_in.data_in_val, (u_int *) &objp->data_in.data_in_len, ~0)) + return FALSE; + return TRUE; + } else if (xdrs->x_op == XDR_DECODE) { + if (!xdr_Device_Link (xdrs, &objp->lid)) + return FALSE; + if (!xdr_Device_Flags (xdrs, &objp->flags)) + return FALSE; + buf = XDR_INLINE (xdrs, 5 * BYTES_PER_XDR_UNIT); + if (buf == NULL) { + if (!xdr_u_long (xdrs, &objp->io_timeout)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->lock_timeout)) + return FALSE; + if (!xdr_long (xdrs, &objp->cmd)) + return FALSE; + if (!xdr_bool (xdrs, &objp->network_order)) + return FALSE; + if (!xdr_long (xdrs, &objp->datasize)) + return FALSE; + + } else { + objp->io_timeout = IXDR_GET_U_LONG(buf); + objp->lock_timeout = IXDR_GET_U_LONG(buf); + objp->cmd = IXDR_GET_LONG(buf); + objp->network_order = IXDR_GET_BOOL(buf); + objp->datasize = IXDR_GET_LONG(buf); + } + if (!xdr_bytes (xdrs, (char **)&objp->data_in.data_in_val, (u_int *) &objp->data_in.data_in_len, ~0)) + return FALSE; + return TRUE; + } + + if (!xdr_Device_Link (xdrs, &objp->lid)) + return FALSE; + if (!xdr_Device_Flags (xdrs, &objp->flags)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->io_timeout)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->lock_timeout)) + return FALSE; + if (!xdr_long (xdrs, &objp->cmd)) + return FALSE; + if (!xdr_bool (xdrs, &objp->network_order)) + return FALSE; + if (!xdr_long (xdrs, &objp->datasize)) + return FALSE; + if (!xdr_bytes (xdrs, (char **)&objp->data_in.data_in_val, (u_int *) &objp->data_in.data_in_len, ~0)) + return FALSE; + return TRUE; +} + +bool_t +xdr_Device_DocmdResp (XDR *xdrs, Device_DocmdResp *objp) +{ + register int32_t *buf; + + if (!xdr_Device_ErrorCode (xdrs, &objp->error)) + return FALSE; + if (!xdr_bytes (xdrs, (char **)&objp->data_out.data_out_val, (u_int *) &objp->data_out.data_out_len, ~0)) + return FALSE; + return TRUE; +} + +bool_t +xdr_Device_SrqParms (XDR *xdrs, Device_SrqParms *objp) +{ + register int32_t *buf; + + if (!xdr_bytes (xdrs, (char **)&objp->handle.handle_val, (u_int *) &objp->handle.handle_len, ~0)) + return FALSE; + return TRUE; +} @@ -4,7 +4,6 @@ #include "error_utils.h" #include "string_utils.h" #include "device-functions.h" -#include "dummy_functions.h" #include "version.h" #include "flash.h" #include "nicutils.h" @@ -30,13 +29,13 @@ /* To add a new menu: 1. add the menu name directly below */ /* 2. add the menu mode list choices directly below */ -/* 3. if it is to be shown on the main menu, update Menu_Update_Display(void); */ +/* 3. if it is to be shown on the main menu, update Show_Main_Menu(void); */ /* 4. update Submenu_Display(void), which builds the submenu */ /* 5. update Submenu_Implement_Changes(void), to do the actual functions */ /* KEY SUBROUTINES: */ -/* Menu_Update_Display(void); - displays the main menu */ +/* Show_Main_Menu(void); - displays the main menu */ /* Menu_Check_Buttons(void); - determines what to show based on button status */ /* (void); - clears any button presses */ /* Menu_Move_Pointer(int move_amount); - moves the pointer up and down the main menu */ @@ -129,8 +128,12 @@ #define mode_network 7200 #define mode_password 7300 #define mode_selfcal 7400 +#define mode_19200 7500 +#define mode_38400 7600 +#define mode_57600 7700 +#define mode_115200 7800 -#define Submenu_maximum_entries 8 /* used to be 4, before scrolling lists were added */ +#define Submenu_maximum_entries 10 /* used to be 4, before scrolling lists were added */ /* what parameter to adjust */ #define Show_frequency 0 @@ -154,9 +157,6 @@ #define Show_avrq_ampl 1900 -// FIXME - eliminate fixed width variables -// FIXME - tidy up menu global vars - /* KEY MENU-JUGGLING VARIABLES - controlling what is actually shown on the display */ int menu_cursor_pos; @@ -198,6 +198,7 @@ float Submenu_Value; /* actual value of the shown parameter (like frequency) int Submenu_extra_fine; /* is the extra-fine mode on? */ +static void update_remote_mode (); static int Menu_Is_Item_Visible(int LCD_entry); static void Menu_Move_Pointer(int move_amount); static void Display_Number_on_LCD(int Is_Item_Visible,int LCD_row,int LCD_col,char *start_string,int Show_What, int significant_digits, int width_of_column); @@ -212,10 +213,13 @@ static void Nonstd_menu_network(void); static void Read_Keypad(int *button_port_val, int *upper_encoder_val, int *lower_encoder_val); -void Menu_Refresh() +#define GPIB_REMOTE_AND_UNLOCKED (globals.Remote.gpib_remote && !globals.Remote.gpib_lock) +#define GPIB_REMOTE_AND_LOCKED (globals.Remote.gpib_remote && globals.Remote.gpib_lock) + + +static void update_remote_mode () { - globals.Changes.update_whole_main_menu = YES; - Menu_Update_Display(); + GPIB_check_remote_status (&globals.Remote.gpib_remote, &globals.Remote.gpib_lock); } @@ -225,11 +229,27 @@ static int Menu_Is_Item_Visible(int LCD_entry) } -void Menu_Update_Display(void) + +void Update_Main_Menu_If_Visible(void) +{ + if ( (globals.MenuStatus.Type_Of_Menu == Main_Menu_On) && + (globals.MenuStatus.Error_Screen == NO) && + (globals.MenuStatus.Nonstd_Display == NO)) { + Show_Main_Menu(); + } +} + + +void Show_Main_Menu(void) { - char a_string[2*LCD_col_width]; - char b_string[2*LCD_col_width]; + if (!globals.Sys.startup_complete) return; + + static GStaticMutex mutex = G_STATIC_MUTEX_INIT; + g_static_mutex_lock (&mutex); // can be triggered simultaneously by local or remote users + + GString *menu_string = g_string_new (""); + int LCD_entry, LCD_row, LCD_col; int sig_dig; /* number of significant digits to display */ int i; @@ -241,7 +261,6 @@ void Menu_Update_Display(void) (globals.MenuStatus.Error_Screen == YES) || (globals.MenuStatus.Nonstd_Display == YES) ) { LCD_clear(); - globals.Changes.update_whole_main_menu = TRUE; } LCD_entry=-1; @@ -275,9 +294,6 @@ void Menu_Update_Display(void) for (chan=0; chan<(globals.Flash.ChanKey_frequency?globals.Flash.channels:1); ++chan) { if (globals.ChannelState[chan].func_mode!=amp_mode_on) { ++LCD_entry; - if (Main_Menu_Structure[LCD_entry]!=Submenu1_freq+chan) { - globals.Changes.update_whole_main_menu=YES; - } Main_Menu_Structure[LCD_entry]=Submenu1_freq+chan; /* keep track of what is displayed */ LCD_row=LCD_entry % LCD_rows; /* find next available row */ LCD_col=((LCD_entry % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width + 1; /* find next available column */ @@ -285,27 +301,27 @@ void Menu_Update_Display(void) show_item=Show_No_Number; if (globals.ChannelState[chan].trigger_source==source_internal) { - strcpy(a_string,"INT"); + menu_string = g_string_append (menu_string, "INT"); show_item=Show_frequency+chan; } else if (globals.ChannelState[chan].trigger_source==source_external) { - strcpy(a_string,"EXT TRIG"); + menu_string = g_string_append (menu_string, "EXT TRIG"); } else if (globals.ChannelState[chan].trigger_source==source_manual) { - strcpy(a_string,"MAN TRIG"); + menu_string = g_string_append (menu_string, "MAN TRIG"); } else if (globals.ChannelState[chan].trigger_source==source_hold) { - strcpy(a_string,"HOLD TRIG"); + menu_string = g_string_append (menu_string, "HOLD TRIG"); } else if (globals.ChannelState[chan].trigger_source==source_immediate) { - strcpy(a_string,"IMMED TRIG"); + menu_string = g_string_append (menu_string, "IMMED TRIG"); } if (globals.Flash.ChanKey_frequency) { - sprintf(b_string, "%d", chan+1); - strcat(a_string,b_string); + g_string_append_printf (menu_string, "%d", chan+1); } if (globals.ChannelState[chan].trigger_source==source_internal) { - strcat(a_string,":"); + menu_string = g_string_append (menu_string, ":"); } - Display_Number_on_LCD((globals.Changes.update_whole_main_menu || globals.Changes.update_freq) && Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,a_string,show_item,sig_dig,LCD_col_width-1); + Display_Number_on_LCD(Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,menu_string->str,show_item,sig_dig,LCD_col_width-1); + g_string_erase (menu_string, 0, -1); } } @@ -314,9 +330,6 @@ void Menu_Update_Display(void) for (chan=0; chan<(globals.Flash.ChanKey_func_mode?globals.Flash.channels:1); ++chan) { if (globals.Flash.is_func_gen[chan]) { ++LCD_entry; - if (Main_Menu_Structure[LCD_entry]!=Submenu1_func+chan) { - globals.Changes.update_whole_main_menu=YES; - } Main_Menu_Structure[LCD_entry]=Submenu1_func+chan; /* keep track of what is displayed */ LCD_row=LCD_entry % LCD_rows; /* find next available row */ LCD_col=((LCD_entry % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width + 1; /* find next available column */ @@ -324,23 +337,23 @@ void Menu_Update_Display(void) show_item=Show_No_Number; if (globals.ChannelState[chan].func_mode==pulse_mode_on) { - strcpy(a_string,"SHAPE:PULSE"); + menu_string = g_string_append (menu_string, "SHAPE:PULSE"); } else if (globals.ChannelState[chan].func_mode==sin_mode_on) { - strcpy(a_string,"SHAPE:SINE"); + menu_string = g_string_append (menu_string, "SHAPE:SINE"); } else if (globals.ChannelState[chan].func_mode==tri_mode_on) { - strcpy(a_string,"SHAPE:TRI"); + menu_string = g_string_append (menu_string, "SHAPE:TRI"); } else if (globals.ChannelState[chan].func_mode==squ_mode_on) { - strcpy(a_string,"SHAPE:SQU"); + menu_string = g_string_append (menu_string, "SHAPE:SQU"); } else if (globals.ChannelState[chan].func_mode==amp_mode_on) { - strcpy(a_string,"SHAPE:AMP"); + menu_string = g_string_append (menu_string, "SHAPE:AMP"); } if (globals.Flash.ChanKey_func_mode) { - sprintf(b_string, "%d", chan+1); - strcat(a_string,b_string); + g_string_append_printf (menu_string, "%d", chan+1); } - Display_Number_on_LCD((globals.Changes.update_whole_main_menu || globals.Changes.update_func) && Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,a_string,show_item,sig_dig,LCD_col_width-1); + Display_Number_on_LCD(Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,menu_string->str,show_item,sig_dig,LCD_col_width-1); + g_string_erase (menu_string, 0, -1); } } @@ -353,25 +366,22 @@ void Menu_Update_Display(void) || (globals.ChannelState[chan].func_mode==dc_mode_on)) ) { ++LCD_entry; - if (Main_Menu_Structure[LCD_entry]!=Submenu1_delay+chan) { - globals.Changes.update_whole_main_menu=YES; - } Main_Menu_Structure[LCD_entry]=Submenu1_delay+chan; LCD_row=LCD_entry % LCD_rows; LCD_col=((LCD_entry % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width + 1; if (globals.ChannelState[chan].double_pulse==double_off) { - strcpy(a_string,"DLY"); + menu_string = g_string_append (menu_string, "DLY"); } else { - strcpy(a_string,"DBL"); + menu_string = g_string_append (menu_string, "DBL"); } if (globals.Flash.ChanKey_delay) { - sprintf(b_string, "%d", chan+1); - strcat(a_string,b_string); + g_string_append_printf (menu_string, "%d", chan+1); } - strcat(a_string,":"); + menu_string = g_string_append (menu_string, ":"); - Display_Number_on_LCD((globals.Changes.update_whole_main_menu || globals.Changes.update_delay) && Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,a_string,Show_delay+chan,sig_dig-globals.Flash.ChanKey_delay,LCD_col_width-1); + Display_Number_on_LCD(Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,menu_string->str,Show_delay+chan,sig_dig,LCD_col_width-1); + g_string_erase (menu_string, 0, -1); } @@ -385,9 +395,6 @@ void Menu_Update_Display(void) ) { ++LCD_entry; - if (Main_Menu_Structure[LCD_entry]!=Submenu1_pw+chan) { - globals.Changes.update_whole_main_menu=YES; - } Main_Menu_Structure[LCD_entry]=Submenu1_pw+chan; LCD_row=LCD_entry % LCD_rows; LCD_col=((LCD_entry % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width + 1; @@ -398,38 +405,35 @@ void Menu_Update_Display(void) if (globals.ChannelState[chan].ab_mode==pw_normal) { if (globals.ChannelState[chan].hold_setting==hold_width) { show_item=Show_pw+chan; - strcpy(a_string,"PW"); + menu_string = g_string_append (menu_string, "PW"); if (globals.Flash.ChanKey_pw) { - sprintf(b_string, "%d", chan+1); - strcat(a_string,b_string); + g_string_append_printf (menu_string, "%d", chan+1); } - strcat(a_string,":"); + menu_string = g_string_append (menu_string, ":"); } else { show_item=Show_duty_cycle+chan; - strcpy(a_string,"DUTY"); + menu_string = g_string_append (menu_string, "DUTY"); if (globals.Flash.ChanKey_pw) { - sprintf(b_string, "%d", chan+1); - strcat(a_string,b_string); + g_string_append_printf (menu_string, "%d", chan+1); } - strcat(a_string,":"); + menu_string = g_string_append (menu_string, ":"); } } else { - strcpy(a_string,"PW"); + menu_string = g_string_append (menu_string, "PW"); if (globals.Flash.ChanKey_pw) { - sprintf(b_string, "%d", chan+1); - strcat(a_string,b_string); + g_string_append_printf (menu_string, "%d", chan+1); } - strcat(a_string," IN=OUT"); + menu_string = g_string_append (menu_string, " IN=OUT"); } } else { - strcpy(a_string,"PW"); + menu_string = g_string_append (menu_string, "PW"); if (globals.Flash.ChanKey_pw) { - sprintf(b_string, "%d", chan+1); - strcat(a_string,b_string); + g_string_append_printf (menu_string, "%d", chan+1); } - strcat(a_string,": DC"); + menu_string = g_string_append (menu_string, ": DC"); } - Display_Number_on_LCD((globals.Changes.update_whole_main_menu || globals.Changes.update_pw) && Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,a_string,show_item,sig_dig-globals.Flash.ChanKey_pw,LCD_col_width-1); + Display_Number_on_LCD(Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,menu_string->str,show_item,sig_dig,LCD_col_width-1); + g_string_erase (menu_string, 0, -1); } } @@ -444,21 +448,18 @@ void Menu_Update_Display(void) ) { ++LCD_entry; - if (Main_Menu_Structure[LCD_entry]!=Submenu1_rise_time+chan) { - globals.Changes.update_whole_main_menu=YES; - } Main_Menu_Structure[LCD_entry]=Submenu1_rise_time+chan; LCD_row=LCD_entry % LCD_rows; LCD_col=((LCD_entry % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width + 1; show_item=Show_rise_time+chan; - strcpy(a_string,"TR"); + menu_string = g_string_append (menu_string, "TR"); if (globals.Flash.ChanKey_rise_time) { - sprintf(b_string, "%d", chan+1); - strcat(a_string,b_string); + g_string_append_printf (menu_string, "%d", chan+1); } - strcat(a_string,":"); - Display_Number_on_LCD((globals.Changes.update_whole_main_menu || globals.Changes.update_rise_time) && Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,a_string,show_item,sig_dig-globals.Flash.ChanKey_rise_time,LCD_col_width-1); + menu_string = g_string_append (menu_string, ":"); + Display_Number_on_LCD(Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,menu_string->str,show_item,sig_dig,LCD_col_width-1); + g_string_erase (menu_string, 0, -1); } } @@ -468,9 +469,6 @@ void Menu_Update_Display(void) for (chan=0; chan<(globals.Flash.ChanKey_amplitude?globals.Flash.channels:1); ++chan) { if ((globals.Flash.voltage_enabled[chan] || globals.Flash.current_enabled[chan]) ) { ++LCD_entry; - if (Main_Menu_Structure[LCD_entry]!=Submenu1_amp+chan) { - globals.Changes.update_whole_main_menu=YES; - } Main_Menu_Structure[LCD_entry]=Submenu1_amp+chan; LCD_row=LCD_entry % LCD_rows; LCD_col=((LCD_entry % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width + 1; @@ -479,28 +477,26 @@ void Menu_Update_Display(void) if (globals.ChannelState[chan].amp_mode==amp_mode_normal) { show_item=Show_amplitude+chan; - strcpy(a_string,"AMP"); + menu_string = g_string_append (menu_string, "AMP"); if (globals.Flash.ChanKey_amplitude) { - sprintf(b_string, "%d", chan+1); - strcat(a_string,b_string); + g_string_append_printf (menu_string, "%d", chan+1); } - strcat(a_string,":"); + menu_string = g_string_append (menu_string, ":"); } else if (globals.ChannelState[chan].amp_mode==amp_mode_ea) { - strcpy(a_string,"AMP"); + menu_string = g_string_append (menu_string, "AMP"); if (globals.Flash.ChanKey_amplitude) { - sprintf(b_string, "%d", chan+1); - strcat(a_string,b_string); + g_string_append_printf (menu_string, "%d", chan+1); } - strcat(a_string,":EXT"); + menu_string = g_string_append (menu_string, ":EXT"); } else if (globals.ChannelState[chan].amp_mode==amp_mode_amplify) { - strcpy(a_string,"AMP"); + menu_string = g_string_append (menu_string, "AMP"); if (globals.Flash.ChanKey_amplitude) { - sprintf(b_string, "%d", chan+1); - strcat(a_string,b_string); + g_string_append_printf (menu_string, "%d", chan+1); } - strcat(a_string,":AMPLFY"); + menu_string = g_string_append (menu_string, ":AMPLFY"); } - Display_Number_on_LCD((globals.Changes.update_whole_main_menu || globals.Changes.update_amp) && Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,a_string,show_item,sig_dig-globals.Flash.ChanKey_amplitude,LCD_col_width-1); + Display_Number_on_LCD(Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,menu_string->str,show_item,sig_dig,LCD_col_width-1); + g_string_erase (menu_string, 0, -1); } } @@ -510,19 +506,16 @@ void Menu_Update_Display(void) if (globals.Flash.enable_avrq_extra_ampls) { for (chan=2; chan<5; ++chan) { ++LCD_entry; - if (Main_Menu_Structure[LCD_entry]!=Submenu1_avrq+chan) { - globals.Changes.update_whole_main_menu=YES; - } Main_Menu_Structure[LCD_entry]=Submenu1_avrq+chan; LCD_row=LCD_entry % LCD_rows; LCD_col=((LCD_entry % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width + 1; show_item=Show_avrq_ampl+chan; - strcpy(a_string,"AMP"); - sprintf(b_string, "%d", chan+1); - strcat(a_string,b_string); - strcat(a_string,":"); - Display_Number_on_LCD((globals.Changes.update_whole_main_menu || globals.Changes.update_amp) && Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,a_string,show_item,sig_dig-1,LCD_col_width-1); + menu_string = g_string_append (menu_string, "AMP"); + g_string_append_printf (menu_string, "%d", chan+1); + menu_string = g_string_append (menu_string, ":"); + Display_Number_on_LCD(Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,menu_string->str,show_item,sig_dig,LCD_col_width-1); + g_string_erase (menu_string, 0, -1); } } @@ -532,21 +525,18 @@ void Menu_Update_Display(void) if (globals.Flash.soft_current_limit_enabled[chan]) { ++LCD_entry; - if (Main_Menu_Structure[LCD_entry]!=Submenu1_soft_current_limit+chan) { - globals.Changes.update_whole_main_menu=YES; - } Main_Menu_Structure[LCD_entry]=Submenu1_soft_current_limit+chan; LCD_row=LCD_entry % LCD_rows; LCD_col=((LCD_entry % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width + 1; show_item=Show_soft_current_limit+chan; - strcpy(a_string,"LIM"); + menu_string = g_string_append (menu_string, "LIM"); if (globals.Flash.ChanKey_current_limit) { - sprintf(b_string, "%d", chan+1); - strcat(a_string,b_string); + g_string_append_printf (menu_string, "%d", chan+1); } - strcat(a_string,":"); - Display_Number_on_LCD((globals.Changes.update_whole_main_menu || globals.Changes.update_soft_current_limit) && Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,a_string,show_item,sig_dig-globals.Flash.ChanKey_current_limit,LCD_col_width-1); + menu_string = g_string_append (menu_string, ":"); + Display_Number_on_LCD(Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,menu_string->str,show_item,sig_dig,LCD_col_width-1); + g_string_erase (menu_string, 0, -1); } } @@ -558,21 +548,18 @@ void Menu_Update_Display(void) if ( globals.Flash.curr_slew[chan] ) { ++LCD_entry; - if (Main_Menu_Structure[LCD_entry]!=Submenu1_slew+chan) { - globals.Changes.update_whole_main_menu=YES; - } Main_Menu_Structure[LCD_entry]=Submenu1_slew+chan; LCD_row=LCD_entry % LCD_rows; LCD_col=((LCD_entry % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width + 1; show_item=Show_slew+chan; - strcpy(a_string,"SL"); + menu_string = g_string_append (menu_string, "SL"); if (globals.Flash.ChanKey_slew) { - sprintf(b_string, "%d", chan+1); - strcat(a_string,b_string); + g_string_append_printf (menu_string, "%d", chan+1); } - strcat(a_string,":"); - Display_Number_on_LCD((globals.Changes.update_whole_main_menu || globals.Changes.update_slew) && Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,a_string,show_item,sig_dig-globals.Flash.ChanKey_slew,LCD_col_width-1); + menu_string = g_string_append (menu_string, ":"); + Display_Number_on_LCD(Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,menu_string->str,show_item,sig_dig,LCD_col_width-1); + g_string_erase (menu_string, 0, -1); } } @@ -583,21 +570,18 @@ void Menu_Update_Display(void) if (globals.Flash.max_burst_count[chan]>1) { ++LCD_entry; - if (Main_Menu_Structure[LCD_entry]!=Submenu1_burst_count+chan) { - globals.Changes.update_whole_main_menu=YES; - } Main_Menu_Structure[LCD_entry]=Submenu1_burst_count+chan; LCD_row=LCD_entry % LCD_rows; LCD_col=((LCD_entry % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width + 1; show_item=Show_Burst_Count+chan; - strcpy(a_string,"N"); + menu_string = g_string_append (menu_string, "N"); if (globals.Flash.ChanKey_Burst_Count) { - sprintf(b_string, "%d", chan+1); - strcat(a_string,b_string); + g_string_append_printf (menu_string, "%d", chan+1); } - strcat(a_string,":"); - Display_Number_on_LCD((globals.Changes.update_whole_main_menu || globals.Changes.update_burst_count) && Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,a_string,show_item,0,LCD_col_width-1); + menu_string = g_string_append (menu_string, ":"); + Display_Number_on_LCD(Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,menu_string->str,show_item,0,LCD_col_width-1); + g_string_erase (menu_string, 0, -1); } } @@ -609,21 +593,18 @@ void Menu_Update_Display(void) if ((globals.Flash.max_burst_count[chan]>1) && !globals.Flash.burst_func[chan]) { ++LCD_entry; - if (Main_Menu_Structure[LCD_entry]!=Submenu1_burst_time+chan) { - globals.Changes.update_whole_main_menu=YES; - } Main_Menu_Structure[LCD_entry]=Submenu1_burst_time+chan; LCD_row=LCD_entry % LCD_rows; LCD_col=((LCD_entry % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width + 1; show_item=Show_Burst_Time+chan; - strcpy(a_string,"BUR"); + menu_string = g_string_append (menu_string, "BUR"); if (globals.Flash.ChanKey_Burst_Time) { - sprintf(b_string, "%d", chan+1); - strcat(a_string,b_string); + g_string_append_printf (menu_string, "%d", chan+1); } - strcat(a_string,":"); - Display_Number_on_LCD((globals.Changes.update_whole_main_menu || globals.Changes.update_burst_time) && Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,a_string,show_item,sig_dig-globals.Flash.ChanKey_Burst_Time,LCD_col_width-1); + menu_string = g_string_append (menu_string, ":"); + Display_Number_on_LCD(Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,menu_string->str,show_item,sig_dig,LCD_col_width-1); + g_string_erase (menu_string, 0, -1); } } @@ -635,9 +616,6 @@ void Menu_Update_Display(void) if ((globals.Flash.voltage_offset_enabled[chan] || globals.Flash.current_offset_enabled[chan]) && (globals.ChannelState[chan].amp_mode!=amp_mode_amplify)) { ++LCD_entry; - if (Main_Menu_Structure[LCD_entry]!=Submenu1_offset+chan) { - globals.Changes.update_whole_main_menu=YES; - } Main_Menu_Structure[LCD_entry]=Submenu1_offset+chan; LCD_row=LCD_entry % LCD_rows; LCD_col=((LCD_entry % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width + 1; @@ -646,21 +624,20 @@ void Menu_Update_Display(void) if (globals.ChannelState[chan].os_mode==os_mode_normal) { show_item=Show_offset+chan; - strcpy(a_string,"OS"); + menu_string = g_string_append (menu_string, "OS"); if (globals.Flash.ChanKey_offset) { - sprintf(b_string, "%d", chan+1); - strcat(a_string,b_string); + g_string_append_printf (menu_string, "%d", chan+1); } - strcat(a_string,":"); + menu_string = g_string_append (menu_string, ":"); } else { - strcpy(a_string,"OS"); + menu_string = g_string_append (menu_string, "OS"); if (globals.Flash.ChanKey_offset) { - sprintf(b_string, "%d", chan+1); - strcat(a_string,b_string); + g_string_append_printf (menu_string, "%d", chan+1); } - strcat(a_string,":EXT"); + menu_string = g_string_append (menu_string, ":EXT"); } - Display_Number_on_LCD((globals.Changes.update_whole_main_menu || globals.Changes.update_os) && Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,a_string,show_item,sig_dig-globals.Flash.ChanKey_offset,LCD_col_width-1); + Display_Number_on_LCD(Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,menu_string->str,show_item,sig_dig,LCD_col_width-1); + g_string_erase (menu_string, 0, -1); } } @@ -673,13 +650,13 @@ void Menu_Update_Display(void) LCD_row=LCD_entry % LCD_rows; LCD_col=((LCD_entry % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width + 1; - strcpy(a_string,"Mon"); + menu_string = g_string_append (menu_string, "Mon"); if (globals.Flash.ChanKey_Curr_Mon_value) { - sprintf(b_string, "%d", chan+1); - strcat(a_string,b_string); + g_string_append_printf (menu_string, "%d", chan+1); } - strcat(a_string,":"); - Display_Number_on_LCD(Menu_Is_Item_Visible(LCD_entry),LCD_row,LCD_col,a_string,Show_monitor+chan,sig_dig-globals.Flash.ChanKey_Curr_Mon_value,LCD_col_width-1); + menu_string = g_string_append (menu_string, ":"); + Display_Number_on_LCD(Menu_Is_Item_Visible(LCD_entry),LCD_row,LCD_col,menu_string->str,Show_monitor+chan,sig_dig,LCD_col_width-1); + g_string_erase (menu_string, 0, -1); globals.ChannelState[chan].displayed_mon_val=globals.ChannelState[chan].Curr_Mon_value; } } @@ -691,31 +668,24 @@ void Menu_Update_Display(void) for (chan=0; chan<(globals.Flash.ChanKey_zout?globals.Flash.channels:1); ++chan) { if (globals.Flash.switchable_zout[chan] && !globals.Flash.volt_ctrl_pw[chan]) { ++LCD_entry; - if (Main_Menu_Structure[LCD_entry]!=Submenu1_zout+chan) { - globals.Changes.update_whole_main_menu=YES; - } Main_Menu_Structure[LCD_entry]=Submenu1_zout+chan; LCD_row=LCD_entry % LCD_rows; LCD_col=((LCD_entry % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width + 1; - strcpy(a_string,"Zout"); + menu_string = g_string_append (menu_string, "Zout"); if (globals.Flash.ChanKey_zout) { - sprintf(b_string, "%d", chan+1); - strcat(a_string,b_string); + g_string_append_printf (menu_string, "%d", chan+1); } - strcat(a_string,":"); + menu_string = g_string_append (menu_string, ":"); - gchar *temp = NULL; if (globals.ChannelState[chan].zout==globals.Flash.zout_max[chan]) { - temp = g_strdup_printf ("%d\xf4 ", globals.Flash.zout_max[chan]); - strcat(a_string,temp); + g_string_append_printf (menu_string, "%d\xf4 ", globals.Flash.zout_max[chan]); } else { - temp = g_strdup_printf ("%d\xf4 ", globals.Flash.zout_min[chan]); - strcat(a_string,temp); + g_string_append_printf (menu_string, "%d\xf4 ", globals.Flash.zout_min[chan]); } - g_free (temp); - Display_Number_on_LCD((globals.Changes.update_whole_main_menu || globals.Changes.update_zout) && Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,a_string,Show_No_Number,sig_dig-globals.Flash.ChanKey_zout,LCD_col_width-1); + Display_Number_on_LCD(Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,menu_string->str,Show_No_Number,sig_dig,LCD_col_width-1); + g_string_erase (menu_string, 0, -1); } } @@ -724,21 +694,18 @@ void Menu_Update_Display(void) for (chan=0; chan<(globals.Flash.ChanKey_load_type?globals.Flash.channels:1); ++chan) { if (globals.Flash.switchable_load[chan]) { ++LCD_entry; - if (Main_Menu_Structure[LCD_entry]!=Submenu1_loadtype+chan) { - globals.Changes.update_whole_main_menu=YES; - } Main_Menu_Structure[LCD_entry]=Submenu1_loadtype+chan; LCD_row=LCD_entry % LCD_rows; LCD_col=((LCD_entry % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width + 1; show_item=Show_load_type+chan; - strcpy(a_string,"Load"); + menu_string = g_string_append (menu_string, "Load"); if (globals.Flash.ChanKey_load_type) { - sprintf(b_string, "%d", chan+1); - strcat(a_string,b_string); + g_string_append_printf (menu_string, "%d", chan+1); } - strcat(a_string,":"); - Display_Number_on_LCD((globals.Changes.update_whole_main_menu || globals.Changes.update_load) && Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,a_string,show_item,sig_dig-globals.Flash.ChanKey_load_type,LCD_col_width-1); + menu_string = g_string_append (menu_string, ":"); + Display_Number_on_LCD(Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,menu_string->str,show_item,sig_dig,LCD_col_width-1); + g_string_erase (menu_string, 0, -1); } } @@ -748,28 +715,25 @@ void Menu_Update_Display(void) if (globals.Flash.on_off_used) for (chan=0; chan<(globals.Flash.ChanKey_output_state?globals.Flash.channels:1); ++chan) { ++LCD_entry; - if (Main_Menu_Structure[LCD_entry]!=Submenu1_output_state+chan) { - globals.Changes.update_whole_main_menu=YES; - } Main_Menu_Structure[LCD_entry]=Submenu1_output_state+chan; LCD_row=LCD_entry % LCD_rows; LCD_col=((LCD_entry % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width + 1; - strcpy(a_string,"Output"); + menu_string = g_string_append (menu_string, "Output"); if (globals.Flash.ChanKey_output_state) { - sprintf(b_string, "%d", chan+1); - strcat(a_string,b_string); + g_string_append_printf (menu_string, "%d", chan+1); } - strcat(a_string,":"); + menu_string = g_string_append (menu_string, ":"); if (globals.ChannelState[chan].output_state==output_on) { - strcat(a_string,"ON"); + menu_string = g_string_append (menu_string, "ON"); } else { - strcat(a_string,"OFF"); + menu_string = g_string_append (menu_string, "OFF"); } - Display_Number_on_LCD((globals.Changes.update_whole_main_menu || globals.Changes.update_output) && Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,a_string,Show_No_Number,sig_dig-globals.Flash.ChanKey_output_state,LCD_col_width-1); + Display_Number_on_LCD(Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,menu_string->str,Show_No_Number,sig_dig,LCD_col_width-1); + g_string_erase (menu_string, 0, -1); } /*----- display primary routing, as appropriate -----*/ @@ -778,9 +742,6 @@ void Menu_Update_Display(void) if (globals.Flash.routing_required[chan] > 0) { ++LCD_entry; - if (Main_Menu_Structure[LCD_entry]!=Submenu1_route_primary+chan) { - globals.Changes.update_whole_main_menu=YES; - } Main_Menu_Structure[LCD_entry]=Submenu1_route_primary+chan; LCD_row=LCD_entry % LCD_rows; LCD_col=((LCD_entry % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width + 1; @@ -788,17 +749,17 @@ void Menu_Update_Display(void) show_item=Show_route_primary+chan; if (globals.Flash.routing_required[chan] == 1) { - strcpy(a_string,"Route"); + menu_string = g_string_append (menu_string, "Route"); } else { - strcpy(a_string,"ANOD"); + menu_string = g_string_append (menu_string, "ANOD"); } if (globals.Flash.ChanKey_route) { - sprintf(b_string, "%d", chan+1); - strcat(a_string,b_string); + g_string_append_printf (menu_string, "%d", chan+1); } - strcat(a_string,":"); - Display_Number_on_LCD((globals.Changes.update_whole_main_menu || globals.Changes.update_routes) && Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,a_string,show_item,0,LCD_col_width-1); + menu_string = g_string_append (menu_string, ":"); + Display_Number_on_LCD(Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,menu_string->str,show_item,0,LCD_col_width-1); + g_string_erase (menu_string, 0, -1); } } @@ -809,23 +770,20 @@ void Menu_Update_Display(void) if (globals.Flash.routing_required[chan] == 2) { ++LCD_entry; - if (Main_Menu_Structure[LCD_entry]!=Submenu1_route_secondary+chan) { - globals.Changes.update_whole_main_menu=YES; - } Main_Menu_Structure[LCD_entry]=Submenu1_route_secondary+chan; LCD_row=LCD_entry % LCD_rows; LCD_col=((LCD_entry % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width + 1; show_item=Show_route_secondary+chan; - strcpy(a_string,"CATH"); + menu_string = g_string_append (menu_string, "CATH"); if (globals.Flash.ChanKey_route) { - sprintf(b_string, "%d", chan+1); - strcat(a_string,b_string); + g_string_append_printf (menu_string, "%d", chan+1); } - strcat(a_string,":"); - Display_Number_on_LCD((globals.Changes.update_whole_main_menu || globals.Changes.update_routes) && Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,a_string,show_item,0,LCD_col_width-1); + menu_string = g_string_append (menu_string, ":"); + Display_Number_on_LCD(Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,menu_string->str,show_item,0,LCD_col_width-1); + g_string_erase (menu_string, 0, -1); } } @@ -835,27 +793,24 @@ void Menu_Update_Display(void) for (chan=0; chan<(globals.Flash.ChanKey_polarity?globals.Flash.channels:1); ++chan) { if (globals.Flash.invert_allowed[chan]) { ++LCD_entry; - if (Main_Menu_Structure[LCD_entry]!=Submenu1_invert+chan) { - globals.Changes.update_whole_main_menu=YES; - } Main_Menu_Structure[LCD_entry]=Submenu1_invert+chan; LCD_row=LCD_entry % LCD_rows; LCD_col=((LCD_entry % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width + 1; - strcpy(a_string,"INVERT"); + menu_string = g_string_append (menu_string, "INVERT"); if (globals.Flash.ChanKey_polarity) { - sprintf(b_string, "%d", chan+1); - strcat(a_string,b_string); + g_string_append_printf (menu_string, "%d", chan+1); } - strcat(a_string,":"); + menu_string = g_string_append (menu_string, ":"); if (globals.ChannelState[chan].polarity==pol_norm) { - strcat(a_string,"NO"); + menu_string = g_string_append (menu_string, "NO"); } else { - strcat(a_string,"YES"); + menu_string = g_string_append (menu_string, "YES"); } - Display_Number_on_LCD((globals.Changes.update_whole_main_menu || globals.Changes.update_inv) && Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,a_string,Show_No_Number,sig_dig-globals.Flash.ChanKey_polarity,LCD_col_width-1); + Display_Number_on_LCD(Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,menu_string->str,Show_No_Number,sig_dig,LCD_col_width-1); + g_string_erase (menu_string, 0, -1); } } @@ -864,26 +819,23 @@ void Menu_Update_Display(void) if (globals.Flash.logic_level_enabled) { for (chan=0; chan<(globals.Flash.ChanKey_logic_level?globals.Flash.channels:1); ++chan) { ++LCD_entry; - if (Main_Menu_Structure[LCD_entry]!=Submenu1_logic_level+chan) { - globals.Changes.update_whole_main_menu=YES; - } Main_Menu_Structure[LCD_entry]=Submenu1_logic_level+chan; LCD_row=LCD_entry % LCD_rows; LCD_col=((LCD_entry % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width + 1; - strcpy(a_string,"Logic"); + menu_string = g_string_append (menu_string, "Logic"); if (globals.Flash.ChanKey_logic_level) { - sprintf(b_string, "%d", chan+1); - strcat(a_string,b_string); + g_string_append_printf (menu_string, "%d", chan+1); } - strcat(a_string,":"); + menu_string = g_string_append (menu_string, ":"); if (globals.ChannelState[chan].logic_level==logic_ttl) { - strcat(a_string,"TTL"); + menu_string = g_string_append (menu_string, "TTL"); } else { - strcat(a_string,"ECL"); + menu_string = g_string_append (menu_string, "ECL"); } - Display_Number_on_LCD((globals.Changes.update_whole_main_menu || globals.Changes.update_logic_level) && Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,a_string,Show_No_Number,sig_dig-globals.Flash.ChanKey_logic_level,LCD_col_width-1); + Display_Number_on_LCD(Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,menu_string->str,Show_No_Number,sig_dig,LCD_col_width-1); + g_string_erase (menu_string, 0, -1); } } @@ -894,72 +846,86 @@ void Menu_Update_Display(void) if (!globals.Flash.is_func_gen[chan]) { { ++LCD_entry; - if (Main_Menu_Structure[LCD_entry]!=Submenu1_gate+chan) { - globals.Changes.update_whole_main_menu=YES; - } Main_Menu_Structure[LCD_entry]=Submenu1_gate+chan; LCD_row=LCD_entry % LCD_rows; LCD_col=((LCD_entry % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width + 1; - strcpy(a_string,"GAT"); + menu_string = g_string_append (menu_string, "GAT"); if (globals.Flash.ChanKey_gate_type || globals.Flash.ChanKey_gate_level) { - sprintf(b_string, "%d", chan+1); - strcat(a_string,b_string); + g_string_append_printf (menu_string, "%d", chan+1); } - strcat(a_string,":"); + menu_string = g_string_append (menu_string, ":"); if (globals.ChannelState[chan].gate_type==gate_sync && globals.ChannelState[chan].gate_level==gate_low) { - strcat(a_string,"SYN,LO"); + menu_string = g_string_append (menu_string, "SYN,LO"); } else if (globals.ChannelState[chan].gate_type==gate_sync && globals.ChannelState[chan].gate_level==gate_high) { - strcat(a_string,"SYN,HI"); + menu_string = g_string_append (menu_string, "SYN,HI"); } else if (globals.ChannelState[chan].gate_type==gate_async && globals.ChannelState[chan].gate_level==gate_low) { - strcat(a_string,"ASY,LO"); + menu_string = g_string_append (menu_string, "ASY,LO"); } else { - strcat(a_string,"ASY,HI"); + menu_string = g_string_append (menu_string, "ASY,HI"); } - Display_Number_on_LCD((globals.Changes.update_whole_main_menu || globals.Changes.update_gate) && Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,a_string,Show_No_Number, sig_dig-(globals.Flash.ChanKey_gate_level | globals.Flash.ChanKey_gate_type),LCD_col_width-1); + Display_Number_on_LCD(Menu_Is_Item_Visible(LCD_entry), LCD_row,LCD_col,menu_string->str,Show_No_Number, sig_dig,LCD_col_width-1); + g_string_erase (menu_string, 0, -1); } } /*----- display remote/local, always -----*/ ++LCD_entry; - if (Main_Menu_Structure[LCD_entry]!=Submenu1_rem_loc) { - globals.Changes.update_whole_main_menu=YES; - } Main_Menu_Structure[LCD_entry]=Submenu1_rem_loc; LCD_row=LCD_entry % LCD_rows; LCD_col=((LCD_entry % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width + 1; - gchar *ctrl_str = NULL; + update_remote_mode(); - switch (globals.control_mode) { - case REMS_ctrl: - ctrl_str = g_strdup ("GPIB CTRL"); - break; - case RWLS_ctrl: - ctrl_str = g_strdup ("GPIB LOCK"); - break; - case RS232_ctrl: - ctrl_str = g_strdup ("RS232 CTRL"); - break; - case WEB_ctrl: - ctrl_str = g_strdup ("WEB CTRL"); - break; - case TELNET_ctrl: - ctrl_str = g_strdup ("TELNET CTRL"); - break; - case LWLS_ctrl: - ctrl_str = g_strdup ("LOCAL LOCK"); - break; - case LOCS_ctrl: - default: - ctrl_str = g_strdup ("LOCAL CTRL"); - break; + GString *raw_str = g_string_new (""); + + if (!GPIB_REMOTE_AND_LOCKED) { + raw_str = g_string_append (raw_str, "LOCAL+"); } - if (globals.Changes.update_whole_main_menu && Menu_Is_Item_Visible(LCD_entry)) { + if (globals.Remote.gpib_remote) { + raw_str = g_string_append (raw_str, "GPIB+"); + } + + if (globals.Remote.terminal_connections > 0) { + g_string_append_printf (raw_str, "%dTER", globals.Remote.terminal_connections); + } + + if (globals.Remote.vxi_connections > 0) { + g_string_append_printf (raw_str, "%dVXI", globals.Remote.vxi_connections); + } + + gchar *step1 = g_strdup (raw_str->str); + g_string_free (raw_str, TRUE); + + // remove semicolon at end + gchar *step2 = conditional_regex_replace (TRUE, step1, "\\+$", ""); + g_free (step1); + + // shorten as required + gchar *step3 = conditional_regex_replace (strlen(step2) > LCD_col_width, step2, "LOCAL", "LO"); + g_free (step2); + + // shorten as required + gchar *step4 = conditional_regex_replace (strlen(step3) > LCD_col_width, step3, "TER", "T"); + g_free (step3); + + // shorten as required + gchar *step5 = conditional_regex_replace (strlen(step4) > LCD_col_width, step4, "GPIB", "GP"); + g_free (step4); + + // shorten as required + gchar *step6 = conditional_regex_replace (strlen(step5) > LCD_col_width, step5, "VXI", "V"); + g_free (step5); + + // finish + gchar *ctrl_str = g_strdup (step6); + g_free (step6); + + if (Menu_Is_Item_Visible(LCD_entry)) { LCD_write_padded_spaces(LCD_row,LCD_col,ctrl_str,LCD_col_width); } @@ -968,14 +934,11 @@ void Menu_Update_Display(void) /*----- display memory, always -----*/ ++LCD_entry; - if (Main_Menu_Structure[LCD_entry]!=Submenu1_memory) { - globals.Changes.update_whole_main_menu=YES; - } Main_Menu_Structure[LCD_entry]=Submenu1_memory; LCD_row=LCD_entry % LCD_rows; LCD_col=((LCD_entry % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width + 1; - if (globals.Changes.update_whole_main_menu && Menu_Is_Item_Visible(LCD_entry)) { + if (Menu_Is_Item_Visible(LCD_entry)) { LCD_write_padded_spaces(LCD_row,LCD_col,"Memory menu",LCD_col_width); } @@ -983,14 +946,11 @@ void Menu_Update_Display(void) /*----- display setup, always -----*/ ++LCD_entry; - if (Main_Menu_Structure[LCD_entry]!=Submenu1_setup) { - globals.Changes.update_whole_main_menu=YES; - } Main_Menu_Structure[LCD_entry]=Submenu1_setup; LCD_row=LCD_entry % LCD_rows; LCD_col=((LCD_entry % LCD_max_entries_per_page) / LCD_rows) * LCD_col_width + 1; - if (globals.Changes.update_whole_main_menu && Menu_Is_Item_Visible(LCD_entry)) { + if (Menu_Is_Item_Visible(LCD_entry)) { LCD_write_padded_spaces(LCD_row,LCD_col,"Setup menu",LCD_col_width); } @@ -1022,7 +982,9 @@ void Menu_Update_Display(void) LCD_write_padded_spaces(LCD_row,LCD_col,"",LCD_col_width); } - globals.Changes.update_whole_main_menu=NO; + g_string_free (menu_string, TRUE); + + g_static_mutex_unlock (&mutex); } @@ -1075,20 +1037,21 @@ static void Menu_Move_Pointer(int move_amount) new_page=menu_cursor_pos / LCD_max_entries_per_page; if (new_page!=old_page) { - Menu_Refresh(); + Show_Main_Menu(); } - } static void Display_Number_on_LCD(int Is_Item_Visible,int LCD_row,int LCD_col,char *start_string,int Show_What, int significant_digits, int width_of_column) { + if (!Is_Item_Visible) { + return; + } + + gchar *LCD_string = NULL; gchar *units = NULL; int channel; - char LCD_string[LCD_cols+1]; - LCD_string[0]=0; - channel=Show_What%100; if (Show_What!=Show_No_Number) { @@ -1228,15 +1191,14 @@ static void Display_Number_on_LCD(int Is_Item_Visible,int LCD_row,int LCD_col,ch units = g_strdup(""); } - String_Parameter_To_Text(Submenu_Value,significant_digits,start_string,units,LCD_string,show_plus_sign); + String_Parameter_To_Text(Submenu_Value,significant_digits,start_string,units,&LCD_string,show_plus_sign,width_of_column); } else { - strcpy(LCD_string,start_string); + LCD_string = g_strdup(start_string); } - if (Is_Item_Visible) { - LCD_write_padded_spaces(LCD_row, LCD_col, LCD_string, width_of_column); - } + LCD_write_padded_spaces(LCD_row, LCD_col, LCD_string, width_of_column); + g_free (LCD_string); g_free (units); } @@ -1247,7 +1209,6 @@ static void Submenu_Display(int change_selection) int i; int channel; - // FIXME - check for redundant clearing if ( (globals.MenuStatus.Type_Of_Menu != Submenu_On) || (globals.MenuStatus.Error_Screen == YES) || (globals.MenuStatus.Nonstd_Display == YES) || @@ -1510,11 +1471,17 @@ static void Submenu_Display(int change_selection) break; case Submenu1_rem_loc: - title = g_strdup ("Control Mode:"); - Submenu_max_entry=1; - Submenu_Structure[0]=mode_go_to_local; - Submenu_Structure[1]=mode_exit_normal_submenu; + if (GPIB_REMOTE_AND_UNLOCKED) { + Submenu_max_entry=1; + title = g_strdup ("GPIB Remote:"); + Submenu_Structure[0]=mode_go_to_local; + Submenu_Structure[1]=mode_exit_normal_submenu; + } else { + Submenu_max_entry=0; + title = g_strdup ("GPIB interface already in local mode."); + Submenu_Structure[0]=mode_exit_normal_submenu; + } break; case Submenu1_setup: @@ -1574,38 +1541,17 @@ static void Submenu_Display(int change_selection) case Submenu2_rs232_baud: title = g_strdup ("Baud Rate:"); - Submenu_max_entry=3; + Submenu_max_entry=7; - // FIXME: generate structure from valid baud rate list Submenu_Structure[0]=mode_1200; Submenu_Structure[1]=mode_2400; Submenu_Structure[2]=mode_4800; Submenu_Structure[3]=mode_9600; - break; - - case Submenu2_rs232_databits: - title = g_strdup ("Data Bits:"); - Submenu_max_entry=1; - - Submenu_Structure[0]=mode_7bits; - Submenu_Structure[1]=mode_8bits; - break; - - case Submenu2_rs232_parity: - title = g_strdup ("Parity:"); - Submenu_max_entry=2; - - Submenu_Structure[0]=mode_par_none; - Submenu_Structure[1]=mode_par_even; - Submenu_Structure[2]=mode_par_odd; - break; - - case Submenu2_rs232_stopbits: - title = g_strdup ("Stop Bits:"); - Submenu_max_entry=1; + Submenu_Structure[4]=mode_19200; + Submenu_Structure[5]=mode_38400; + Submenu_Structure[6]=mode_57600; + Submenu_Structure[7]=mode_115200; - Submenu_Structure[0]=mode_1bit; - Submenu_Structure[1]=mode_2bits; break; case Submenu2_rs232_hardhand: @@ -1616,14 +1562,6 @@ static void Submenu_Display(int change_selection) Submenu_Structure[1]=mode_hand_off; break; - case Submenu2_rs232_echo: - title = g_strdup ("Echo:"); - Submenu_max_entry=1; - - Submenu_Structure[0]=mode_echo_on; - Submenu_Structure[1]=mode_echo_off; - break; - case Submenu2_gpib_address: title = g_strdup ("GPIB Address:"); Submenu_Numeric_Parameter=Show_gpib_address+channel; @@ -1661,281 +1599,271 @@ static void Submenu_Display(int change_selection) LCD_write(3,0,Press_Change_Message); if (Submenu_max_entry>0) { - char mode_name[Submenu_maximum_entries][LCD_col_width+1]; + + GPtrArray *gparray = g_ptr_array_new (); + int current_operating_mode = 0; LCD_write(0,19,"Mode:"); for (i=0; i<=Submenu_max_entry; ++i) { + gchar *mode_name; + switch (Submenu_Structure[i]-channel) { case mode_freq_int: - strcpy(mode_name[i],"Internal"); + mode_name = g_strdup("Internal"); if (globals.ChannelState[channel].trigger_source==source_internal) { current_operating_mode=i; } break; case mode_freq_ext: - strcpy(mode_name[i],"External"); + mode_name = g_strdup("External"); if (globals.ChannelState[channel].trigger_source==source_external) { current_operating_mode=i; } break; case mode_freq_man: - strcpy(mode_name[i],"Manual"); + mode_name = g_strdup("Manual"); if (globals.ChannelState[channel].trigger_source==source_manual) { current_operating_mode=i; } break; case mode_freq_hold: - strcpy(mode_name[i],"Hold"); + mode_name = g_strdup("Hold"); if (globals.ChannelState[channel].trigger_source==source_hold) { current_operating_mode=i; } break; case mode_func_sin: - strcpy(mode_name[i],"Sine"); + mode_name = g_strdup("Sine"); if (globals.ChannelState[channel].func_mode==sin_mode_on) { current_operating_mode=i; } break; case mode_func_tri: - strcpy(mode_name[i],"Triangle"); + mode_name = g_strdup("Triangle"); if (globals.ChannelState[channel].func_mode==tri_mode_on) { current_operating_mode=i; } break; case mode_func_squ: - strcpy(mode_name[i],"Square"); + mode_name = g_strdup("Square"); if (globals.ChannelState[channel].func_mode==squ_mode_on) { current_operating_mode=i; } break; case mode_func_pulse: - strcpy(mode_name[i],"Pulse"); + mode_name = g_strdup("Pulse"); if (globals.ChannelState[channel].func_mode==pulse_mode_on) { current_operating_mode=i; } break; case mode_func_amp: - strcpy(mode_name[i],"Amplify"); + mode_name = g_strdup("Amplify"); if (globals.ChannelState[channel].func_mode==amp_mode_on) { current_operating_mode=i; } break; case mode_delay_norm: - strcpy(mode_name[i],"Normal"); + mode_name = g_strdup("Normal"); if (globals.ChannelState[channel].double_pulse==double_off) { current_operating_mode=i; } break; case mode_delay_dbl: - strcpy(mode_name[i],"Double Pulse"); + mode_name = g_strdup("Double Pulse"); if (globals.ChannelState[channel].double_pulse==double_on) { current_operating_mode=i; } break; case mode_pw_norm: - strcpy(mode_name[i],"Normal"); + mode_name = g_strdup("Normal"); if (globals.ChannelState[channel].func_mode==pulse_mode_on && globals.ChannelState[channel].hold_setting==hold_width && globals.ChannelState[channel].ab_mode==pw_normal) { current_operating_mode=i; } break; case mode_pw_duty: - strcpy(mode_name[i],"Duty Cycle"); + mode_name = g_strdup("Duty Cycle"); if (globals.ChannelState[channel].func_mode==pulse_mode_on && globals.ChannelState[channel].hold_setting==hold_duty && globals.ChannelState[channel].ab_mode==pw_normal) { current_operating_mode=i; } break; case mode_pw_inout: - strcpy(mode_name[i],"PWin=PWout"); + mode_name = g_strdup("PWin=PWout"); if (globals.ChannelState[channel].func_mode==pulse_mode_on && globals.ChannelState[channel].ab_mode==pw_in_out) { current_operating_mode=i; } break; case mode_pw_dc: - strcpy(mode_name[i],"DC output"); + mode_name = g_strdup("DC output"); if (globals.ChannelState[channel].func_mode==dc_mode_on) { current_operating_mode=i; } break; case mode_output_on: - strcpy(mode_name[i],"Output On"); + mode_name = g_strdup("Output On"); if (globals.ChannelState[channel].output_state==output_on) { current_operating_mode=i; } break; case mode_output_off: - strcpy(mode_name[i],"Output Off"); + mode_name = g_strdup("Output Off"); if (globals.ChannelState[channel].output_state==output_off) { current_operating_mode=i; } break; case mode_go_to_local: - strcpy(mode_name[i],"Go To Local"); + mode_name = g_strdup("Go To Local"); break; case mode_inv_no: - strcpy(mode_name[i],"NO (normal)"); + mode_name = g_strdup("NO (normal)"); if (globals.ChannelState[channel].polarity==pol_norm) { current_operating_mode=i; } break; case mode_inv_yes: - strcpy(mode_name[i],"YES (inverted)"); + mode_name = g_strdup("YES (inverted)"); if (globals.ChannelState[channel].polarity==pol_complement) { current_operating_mode=i; } break; case mode_gate_losync: - strcpy(mode_name[i],"Sync,TTL-low"); + mode_name = g_strdup("Sync,TTL-low"); if (globals.ChannelState[channel].gate_type==gate_sync && globals.ChannelState[channel].gate_level==gate_low) { current_operating_mode=i; } break; case mode_gate_hisync: - strcpy(mode_name[i],"Sync,TTL-hi"); + mode_name = g_strdup("Sync,TTL-hi"); if (globals.ChannelState[channel].gate_type==gate_sync && globals.ChannelState[channel].gate_level==gate_high) { current_operating_mode=i; } break; case mode_gate_loasync: - strcpy(mode_name[i],"Async,TTL-low"); + mode_name = g_strdup("Async,TTL-low"); if (globals.ChannelState[channel].gate_type==gate_async && globals.ChannelState[channel].gate_level==gate_low) { current_operating_mode=i; } break; case mode_gate_hiasync: - strcpy(mode_name[i],"Async,TTL-hi"); + mode_name = g_strdup("Async,TTL-hi"); if (globals.ChannelState[channel].gate_type==gate_async && globals.ChannelState[channel].gate_level==gate_high) { current_operating_mode=i; } break; case mode_gpib_address: - strcpy(mode_name[i],"GPIB address"); + mode_name = g_strdup("GPIB address"); break; case mode_rs232_settings: - strcpy(mode_name[i],"RS232 setup"); + mode_name = g_strdup("RS232 setup"); break; case mode_model_info: - strcpy(mode_name[i],"Model info"); + mode_name = g_strdup("Model info"); break; case mode_network: - strcpy(mode_name[i],"Network info"); + mode_name = g_strdup("Network info"); break; case mode_password: - strcpy(mode_name[i],"Pwd~default"); + mode_name = g_strdup("Pwd~default"); break; case mode_selfcal: - strcpy(mode_name[i],"Self Cal"); + mode_name = g_strdup("Self Cal"); break; case mode_exit_normal_submenu: - strcpy(mode_name[i],"Exit"); + mode_name = g_strdup("Exit"); break; case mode_load: - strcpy(mode_name[i],"Load Settings"); + mode_name = g_strdup("Load Settings"); break; case mode_save: - strcpy(mode_name[i],"Save Settings"); + mode_name = g_strdup("Save Settings"); break; case mode_load_0: - strcpy(mode_name[i],"Storage 0"); + case mode_save_0: + mode_name = g_strdup("Storage 0"); break; case mode_load_1: - strcpy(mode_name[i],"Storage 1"); + case mode_save_1: + mode_name = g_strdup("Storage 1"); break; case mode_load_2: - strcpy(mode_name[i],"Storage 2"); + case mode_save_2: + mode_name = g_strdup("Storage 2"); break; case mode_load_3: - strcpy(mode_name[i],"Storage 3"); - break; - case mode_save_0: - strcpy(mode_name[i],"Storage 0"); - break; - case mode_save_1: - strcpy(mode_name[i],"Storage 1"); - break; - case mode_save_2: - strcpy(mode_name[i],"Storage 2"); - break; - case mode_save_3: - strcpy(mode_name[i],"Storage 3"); + case mode_save_3: + mode_name = g_strdup("Storage 3"); break; case mode_change_rs232: - strcpy(mode_name[i],"Change values"); + mode_name = g_strdup("Change values"); break; case mode_default_rs232: - strcpy(mode_name[i],"Default"); + mode_name = g_strdup("Default"); break; case mode_exit_rs232: - strcpy(mode_name[i],"Exit"); + mode_name = g_strdup("Exit"); break; case mode_zout_max: - strcpy(mode_name[i],"Zout = "); - gchar *temp1 = g_strdup_printf ("%d\xf4", globals.Flash.zout_max[channel]); - strcat(mode_name[i],temp1); - g_free (temp1); + mode_name = g_strdup_printf ("Zout = %d\xf4", globals.Flash.zout_max[channel]); if (globals.ChannelState[channel].zout==globals.Flash.zout_max[channel]) { current_operating_mode=i; } break; case mode_zout_min: - strcpy(mode_name[i],"Zout = "); - gchar *temp2 = g_strdup_printf ("%d\xf4", globals.Flash.zout_min[channel]); - strcat(mode_name[i],temp2); - g_free (temp2); + mode_name = g_strdup_printf ("Zout = %d\xf4", globals.Flash.zout_min[channel]); if (globals.ChannelState[channel].zout==globals.Flash.zout_min[channel]) { current_operating_mode=i; } break; case mode_logic_ttl: - strcpy(mode_name[i],"TTL levels"); + mode_name = g_strdup("TTL levels"); if (globals.ChannelState[channel].logic_level==logic_ttl) { current_operating_mode=i; } break; case mode_logic_ecl: - strcpy(mode_name[i],"ECL levels"); + mode_name = g_strdup("ECL levels"); if (globals.ChannelState[channel].logic_level==logic_ecl) { current_operating_mode=i; } break; case mode_amp_normal: - strcpy(mode_name[i],"Normal"); + mode_name = g_strdup("Normal"); if (globals.ChannelState[channel].amp_mode==amp_mode_normal) { current_operating_mode=i; } break; case mode_amp_ea: - strcpy(mode_name[i],"Ext Control"); + mode_name = g_strdup("Ext Control"); if (globals.ChannelState[channel].amp_mode==amp_mode_ea) { current_operating_mode=i; } break; case mode_amp_amplify: - strcpy(mode_name[i],"Ext Amplify"); + mode_name = g_strdup("Ext Amplify"); if (globals.ChannelState[channel].amp_mode==amp_mode_amplify) { current_operating_mode=i; } break; case mode_os_normal: - strcpy(mode_name[i],"Normal"); + mode_name = g_strdup("Normal"); if (globals.ChannelState[channel].os_mode==os_mode_normal) { current_operating_mode=i; } break; case mode_os_eo: - strcpy(mode_name[i],"Ext Control"); + mode_name = g_strdup("Ext Control"); if (globals.ChannelState[channel].os_mode==os_mode_eo) { current_operating_mode=i; } break; case mode_amp_min: if (globals.Flash.voltage_enabled[channel]) { - String_Parameter_To_Text(globals.Flash.min_ampl[channel],2,"","V",mode_name[i],YES); + String_Parameter_To_Text(globals.Flash.min_ampl[channel],2,"","V",&mode_name,YES,LCD_col_width); } else { - String_Parameter_To_Text(globals.Flash.min_ampl[channel],2,"","A",mode_name[i],YES); + String_Parameter_To_Text(globals.Flash.min_ampl[channel],2,"","A",&mode_name,YES,LCD_col_width); } if (fabs(globals.ChannelState[channel].amplitude-globals.Flash.min_ampl[channel])<globals.Flash.ampl_zero_equiv[channel]) { @@ -1944,9 +1872,9 @@ static void Submenu_Display(int change_selection) break; case mode_amp_max: if (globals.Flash.voltage_enabled[channel]) { - String_Parameter_To_Text(globals.Flash.max_ampl[channel],2,"","V",mode_name[i],YES); + String_Parameter_To_Text(globals.Flash.max_ampl[channel],2,"","V",&mode_name,YES,LCD_col_width); } else { - String_Parameter_To_Text(globals.Flash.max_ampl[channel],2,"","A",mode_name[i],YES); + String_Parameter_To_Text(globals.Flash.max_ampl[channel],2,"","A",&mode_name,YES,LCD_col_width); } if (fabs(globals.ChannelState[channel].amplitude-globals.Flash.max_ampl[channel])<globals.Flash.ampl_zero_equiv[channel]) { @@ -1954,101 +1882,79 @@ static void Submenu_Display(int change_selection) } break; case mode_1200: - strcpy(mode_name[i],"1200 baud"); + mode_name = g_strdup("1200 baud"); if (globals.Flash.baud==1200) { current_operating_mode=i; } break; case mode_2400: - strcpy(mode_name[i],"2400 baud"); + mode_name = g_strdup("2400 baud"); if (globals.Flash.baud==2400) { current_operating_mode=i; } break; case mode_4800: - strcpy(mode_name[i],"4800 baud"); + mode_name = g_strdup("4800 baud"); if (globals.Flash.baud==4800) { current_operating_mode=i; } break; case mode_9600: - strcpy(mode_name[i],"9600 baud"); + mode_name = g_strdup("9600 baud"); if (globals.Flash.baud==9600) { current_operating_mode=i; } break; - case mode_7bits: - strcpy(mode_name[i],"7 bits"); - if (globals.Flash.databits==7) { - current_operating_mode=i; - } - break; - case mode_8bits: - strcpy(mode_name[i],"8 bits"); - if (globals.Flash.databits==8) { - current_operating_mode=i; - } - break; - case mode_par_none: - strcpy(mode_name[i],"None"); - if (globals.Flash.parity==rs232_parity_none) { - current_operating_mode=i; - } - break; - case mode_par_even: - strcpy(mode_name[i],"Even"); - if (globals.Flash.parity==rs232_parity_even) { + case mode_19200: + mode_name = g_strdup("19200 baud"); + if (globals.Flash.baud==19200) { current_operating_mode=i; } break; - case mode_par_odd: - strcpy(mode_name[i],"Odd"); - if (globals.Flash.parity==rs232_parity_odd) { + case mode_38400: + mode_name = g_strdup("38400 baud"); + if (globals.Flash.baud==38400) { current_operating_mode=i; } break; - case mode_1bit: - strcpy(mode_name[i],"1 bit"); - if (globals.Flash.stopbits==1) { + case mode_57600: + mode_name = g_strdup("57600 baud"); + if (globals.Flash.baud==57600) { current_operating_mode=i; } break; - case mode_2bits: - strcpy(mode_name[i],"2 bits"); - if (globals.Flash.stopbits==2) { + case mode_115200: + mode_name = g_strdup("115200 baud"); + if (globals.Flash.baud==115200) { current_operating_mode=i; } break; + case mode_hand_hard: - strcpy(mode_name[i],"Hardware"); + mode_name = g_strdup("Hardware"); if (globals.Flash.hardhand) { current_operating_mode=i; } break; case mode_hand_off: - strcpy(mode_name[i],"None"); + mode_name = g_strdup("None"); if (!globals.Flash.hardhand) { current_operating_mode=i; } break; - case mode_echo_on: - strcpy(mode_name[i],"On"); - if (globals.Flash.echo) { - current_operating_mode=i; - } - break; - case mode_echo_off: - strcpy(mode_name[i],"Off"); - if (!globals.Flash.echo) { - current_operating_mode=i; - } + default: + mode_name = g_strdup("??"); break; } + + g_ptr_array_add (gparray, (gpointer) mode_name); } - /* If change_selection==NO, the submenu is being drawn from scratch. In this case, the arrow pointer points at the - current operating mode. If change_selection=YES, the submenu is being redrawn to scroll the mode list. In this case, - the arrow pointer points at the current selection. */ + /* If change_selection==NO, the submenu is being drawn from scratch. + this case, the arrow pointer points at the current operating mode. + If change_selection=YES, the submenu is being redrawn to scroll + the mode list. In this case, the arrow pointer points at the current + selection. */ if (change_selection==NO && current_operating_mode<4) { base_entry=0; @@ -2056,21 +1962,14 @@ static void Submenu_Display(int change_selection) } else if (change_selection==NO) { base_entry=current_operating_mode-3; Submenu_Selected_Item=current_operating_mode; - } else if (change_selection=YES && Submenu_Selected_Item<4) { + } else if (change_selection==YES && Submenu_Selected_Item<4) { base_entry=0; - } else if (change_selection=YES && Submenu_Selected_Item>=4) { + } else if (change_selection==YES && Submenu_Selected_Item>=4) { base_entry=Submenu_Selected_Item-3; } for (i=base_entry; ( (i<=Submenu_max_entry) && (i< (base_entry+4)) ); ++i) { - int add_spaces, j; - - add_spaces=LCD_col_width-strlen(mode_name[i]); - - for (j=0; j<add_spaces; j++) { - strcat(mode_name[i]," "); - } - LCD_write(i-base_entry,26,mode_name[i]); + LCD_write_padded_to_end_of_line(i-base_entry, 26, g_ptr_array_index (gparray, i)); } LCD_write(Submenu_Selected_Item-base_entry,25,"~"); @@ -2084,6 +1983,8 @@ static void Submenu_Display(int change_selection) LCD_write(3,39,"\x3"); } + g_ptr_array_foreach (gparray, (GFunc) g_free, NULL); + g_ptr_array_free (gparray, TRUE); } } @@ -2139,12 +2040,14 @@ static int Submenu_Mult_Value(float mult_by) new_value=zero_equiv_timing; } } - if (fabs(new_value) < zero_equiv_timing) + + if (fabs(new_value) < zero_equiv_timing) { if (new_value<0.0) { new_value=-smallest_allowed_number; } else { new_value=smallest_allowed_number; } + } if (error_num=Set_Delay(0,0,0,channel,new_value)) { Submenu_Value=new_value; @@ -2160,12 +2063,14 @@ static int Submenu_Mult_Value(float mult_by) new_value=zero_equiv_timing; } } - if (fabs(new_value) < zero_equiv_timing) + + if (fabs(new_value) < zero_equiv_timing) { if (new_value<0.0) { new_value=-smallest_allowed_number; } else { new_value=smallest_allowed_number; } + } if (error_num=Set_Pw(0,0,0,channel,new_value,0)) { Submenu_Value=new_value; @@ -2180,12 +2085,15 @@ static int Submenu_Mult_Value(float mult_by) new_value=globals.Flash.ampl_zero_equiv[channel]; } } - if (fabs(new_value) < globals.Flash.ampl_zero_equiv[channel]) + + if (fabs(new_value) < globals.Flash.ampl_zero_equiv[channel]) { if (new_value<0.0) { new_value=-smallest_allowed_number; } else { new_value=smallest_allowed_number; } + } + if (error_num=Set_Amplitude(0,0,0,0,0,0,channel,new_value,0)) { Submenu_Value=new_value; } @@ -2248,12 +2156,15 @@ static int Submenu_Mult_Value(float mult_by) new_value=globals.Flash.ampl_zero_equiv[channel]; } } - if (fabs(new_value) < globals.Flash.ampl_zero_equiv[channel]) + + if (fabs(new_value) < globals.Flash.ampl_zero_equiv[channel]) { if (new_value<0.0) { new_value=-smallest_allowed_number; } else { new_value=smallest_allowed_number; } + } + if (error_num=Set_Offset(0,0,0,0,channel,new_value)) { Submenu_Value=new_value; } @@ -2289,7 +2200,8 @@ static void Submenu_Service_Encoder(int encoder_change) reset_encoder=YES; /* quit if RWLS mode */ - if (globals.control_mode==RWLS_ctrl) { + update_remote_mode (); + if (GPIB_REMOTE_AND_LOCKED) { return; } @@ -2656,12 +2568,14 @@ static void Submenu_Service_Encoder(int encoder_change) if (globals.Flash.min_ampl[channel]==globals.Flash.max_ampl[channel]) { return; } - if (fabs(new_value) < globals.Flash.ampl_zero_equiv[channel]) + + if (fabs(new_value) < globals.Flash.ampl_zero_equiv[channel]) { if (Submenu_Value<0.0) { new_value=-smallest_allowed_number; } else { new_value=smallest_allowed_number; } + } if (globals.Flash.ampl_min_max_only[channel]) { /* not used for two-state amplitudes */ return; @@ -2762,12 +2676,12 @@ static void Nonstd_menu_default_rs232(void) Menu_Clear_Buttons(); LCD_clear(); /*0123456789012345678901234567890123456789*/ - LCD_write(0,0,"The RS232 settings are now: 1200 baud, "); - LCD_write(1,0,"8 data bits, no parity, 1 stop bit,"); - LCD_write(2,0,"hardware handshaking on, and echo on."); + LCD_write(0,0,"The RS232 settings are now: 1200 baud,"); + LCD_write(1,0,"auto data bits / parity, 1 stop bit,"); + LCD_write(2,0,"hardware handshaking on, echo on."); LCD_write(3,0,Press_Change_Message); - IO_Setup_RS232(1200, rs232_parity_none, 1, 8, 1, 1, TRUE); + IO_Setup_RS232(1200, 1, TRUE); Menu_Clear_Buttons(); @@ -2898,6 +2812,11 @@ void Menu_Check_Buttons(void) int lower_encoder_val; int encoder_change; + // abort if not running on the target board with the I2C bus + if (!globals.HWDetect.beaglebone) { + return; + } + /* get keypad state */ Read_Keypad(&button_port_val,&upper_encoder_val,&lower_encoder_val); @@ -2908,18 +2827,15 @@ void Menu_Check_Buttons(void) encoder_change = encoder_change - 0x100; } + update_remote_mode(); + if (!(button_port_val & Change_Button)) { /* ----- CHANGE BUTTON --------- */ - if ( globals.control_mode==LOCS_ctrl || globals.control_mode==LWLS_ctrl || - ( - ( globals.control_mode==REMS_ctrl - || globals.control_mode==RS232_ctrl - || globals.control_mode==WEB_ctrl - || globals.control_mode==TELNET_ctrl) - && globals.MenuStatus.Selected_Submenu==Submenu1_rem_loc - ) - ) { + if (GPIB_REMOTE_AND_LOCKED) { + // front panel is locked out + Show_Main_Menu(); + } else { if ((globals.MenuStatus.Type_Of_Menu==Main_Menu_On && globals.MenuStatus.Error_Screen==YES) || globals.MenuStatus.Nonstd_Display==YES) { - Menu_Update_Display(); + Show_Main_Menu(); } else if (globals.MenuStatus.Type_Of_Menu==Submenu_On && globals.MenuStatus.Error_Screen==YES) { Submenu_Display(NO); } else if (globals.MenuStatus.Type_Of_Menu==Main_Menu_On && globals.MenuStatus.Error_Screen==NO) { @@ -2939,29 +2855,28 @@ void Menu_Check_Buttons(void) Submenu_Move_Pointer(); } } else if (!(button_port_val & Mult10_Button)) { /* ----- X10 BUTTON ------------ */ - if (globals.MenuStatus.Type_Of_Menu==Submenu_On && (globals.control_mode==LOCS_ctrl || globals.control_mode==LWLS_ctrl)) { + if (globals.MenuStatus.Type_Of_Menu==Submenu_On && !GPIB_REMOTE_AND_LOCKED) { if (globals.MenuStatus.Error_Screen==YES) { Submenu_Display(NO); } queue_error_and_display_on_LCD(Submenu_Mult_Value(10.0)); } } else if (!(button_port_val & Div10_Button)) { /* ----- /10 BUTTON ------------ */ - if (globals.MenuStatus.Type_Of_Menu==Submenu_On && (globals.control_mode==LOCS_ctrl || globals.control_mode==LWLS_ctrl)) { + if (globals.MenuStatus.Type_Of_Menu==Submenu_On && !GPIB_REMOTE_AND_LOCKED) { if (globals.MenuStatus.Error_Screen==YES) { Submenu_Display(NO); } queue_error_and_display_on_LCD(Submenu_Mult_Value(0.1)); } } else if (!(button_port_val & Plus_Minus_Button)) { /* ----- +/- BUTTON ------------ */ - if (globals.MenuStatus.Type_Of_Menu==Submenu_On && (globals.control_mode==LOCS_ctrl || globals.control_mode==LWLS_ctrl)) { + if (globals.MenuStatus.Type_Of_Menu==Submenu_On && !GPIB_REMOTE_AND_LOCKED) { if (globals.MenuStatus.Error_Screen==YES) { Submenu_Display(NO); } queue_error_and_display_on_LCD(Submenu_Mult_Value(-1.0)); } } else if (!(button_port_val & Extra_Fine_Button)) { /* ----- EXTRA FINE BUTTON ----- */ - if (globals.MenuStatus.Type_Of_Menu==Submenu_On && globals.MenuStatus.Nonstd_Display==NO && globals.MenuStatus.Error_Screen==NO && - (globals.control_mode==LOCS_ctrl || globals.control_mode==LWLS_ctrl)) { + if (globals.MenuStatus.Type_Of_Menu==Submenu_On && globals.MenuStatus.Nonstd_Display==NO && globals.MenuStatus.Error_Screen==NO && !GPIB_REMOTE_AND_LOCKED) { if (Submenu_extra_fine==YES) { g_usleep (250e3); Submenu_extra_fine=NO; @@ -2990,14 +2905,14 @@ static int Submenu_Implement_Changes(void) { int error_num; int call_new_submenu; - int channel,eprom_loc; + int channel; call_new_submenu=NO; /* this routine changes the pulse generator parameters, as chosen by the submenu settings */ if (Submenu_max_entry==0) { - Menu_Update_Display(); + Show_Main_Menu(); return OK; } @@ -3116,7 +3031,7 @@ static int Submenu_Implement_Changes(void) } break; case mode_go_to_local: - Main_return_to_local(); + GPIB_go_to_local(); break; case mode_inv_no: if (error_num=Set_Pol(channel,pol_norm)) { @@ -3254,8 +3169,8 @@ static int Submenu_Implement_Changes(void) Submenu_Display(NO); break; case mode_default_rs232: + call_new_submenu=YES; Nonstd_menu_default_rs232(); - globals.MenuStatus.Selected_Submenu=Submenu1_setup; break; case mode_model_info: call_new_submenu=YES; @@ -3266,11 +3181,7 @@ static int Submenu_Implement_Changes(void) Nonstd_menu_network(); break; case mode_password: - strcpy(globals.Flash.password,"default"); - // FIXME - save password to /etc/shadow here - - eprom_loc = (char *) &(globals.Flash.password) - (char *) &(globals.Flash.flash_start); - writeUserBlock(&globals.Flash, eprom_loc, strlen(globals.Flash.password)+1); + change_password (NULL, "default"); break; case mode_selfcal: if (error_num=self_cal()) { @@ -3286,99 +3197,72 @@ static int Submenu_Implement_Changes(void) globals.MenuStatus.Selected_Submenu=Submenu1_setup; break; case mode_1200: - // FIXME: check that serial menus actually work - IO_Setup_RS232(1200, globals.Flash.parity, globals.Flash.stopbits, globals.Flash.databits, globals.Flash.hardhand, globals.Flash.echo, FALSE); - globals.MenuStatus.Selected_Submenu=Submenu2_rs232_databits; + IO_Setup_RS232(1200, globals.Flash.hardhand, FALSE); + globals.MenuStatus.Selected_Submenu=Submenu2_rs232_hardhand; call_new_submenu=YES; Submenu_Display(NO); break; case mode_2400: - IO_Setup_RS232(2400, globals.Flash.parity, globals.Flash.stopbits, globals.Flash.databits, globals.Flash.hardhand, globals.Flash.echo, FALSE); - globals.MenuStatus.Selected_Submenu=Submenu2_rs232_databits; + IO_Setup_RS232(2400, globals.Flash.hardhand, FALSE); + globals.MenuStatus.Selected_Submenu=Submenu2_rs232_hardhand; call_new_submenu=YES; Submenu_Display(NO); break; case mode_4800: - IO_Setup_RS232(4800, globals.Flash.parity, globals.Flash.stopbits, globals.Flash.databits, globals.Flash.hardhand, globals.Flash.echo, FALSE); - globals.MenuStatus.Selected_Submenu=Submenu2_rs232_databits; + IO_Setup_RS232(4800, globals.Flash.hardhand, FALSE); + globals.MenuStatus.Selected_Submenu=Submenu2_rs232_hardhand; call_new_submenu=YES; Submenu_Display(NO); break; case mode_9600: - IO_Setup_RS232(9600, globals.Flash.parity, globals.Flash.stopbits, globals.Flash.databits, globals.Flash.hardhand, globals.Flash.echo, FALSE); - globals.MenuStatus.Selected_Submenu=Submenu2_rs232_databits; - call_new_submenu=YES; - Submenu_Display(NO); - break; - case mode_7bits: - IO_Setup_RS232(globals.Flash.baud, globals.Flash.parity, 7, globals.Flash.databits, globals.Flash.hardhand, globals.Flash.echo, FALSE); - globals.MenuStatus.Selected_Submenu=Submenu2_rs232_parity; - call_new_submenu=YES; - Submenu_Display(NO); - break; - case mode_8bits: - IO_Setup_RS232(globals.Flash.baud, globals.Flash.parity, 8, globals.Flash.databits, globals.Flash.hardhand, globals.Flash.echo, FALSE); - globals.MenuStatus.Selected_Submenu=Submenu2_rs232_parity; - call_new_submenu=YES; - Submenu_Display(NO); - break; - case mode_par_none: - IO_Setup_RS232(globals.Flash.baud, rs232_parity_none, globals.Flash.stopbits, globals.Flash.databits, globals.Flash.hardhand, globals.Flash.echo, FALSE); - globals.MenuStatus.Selected_Submenu=Submenu2_rs232_stopbits; + IO_Setup_RS232(9600, globals.Flash.hardhand, FALSE); + globals.MenuStatus.Selected_Submenu=Submenu2_rs232_hardhand; call_new_submenu=YES; Submenu_Display(NO); break; - case mode_par_odd: - IO_Setup_RS232(globals.Flash.baud, rs232_parity_odd, globals.Flash.stopbits, globals.Flash.databits, globals.Flash.hardhand, globals.Flash.echo, FALSE); - globals.MenuStatus.Selected_Submenu=Submenu2_rs232_stopbits; + case mode_19200: + IO_Setup_RS232(19200, globals.Flash.hardhand, FALSE); + globals.MenuStatus.Selected_Submenu=Submenu2_rs232_hardhand; call_new_submenu=YES; Submenu_Display(NO); break; - case mode_par_even: - IO_Setup_RS232(globals.Flash.baud, rs232_parity_even, globals.Flash.stopbits, globals.Flash.databits, globals.Flash.hardhand, globals.Flash.echo, FALSE); - globals.MenuStatus.Selected_Submenu=Submenu2_rs232_stopbits; + case mode_38400: + IO_Setup_RS232(38400, globals.Flash.hardhand, FALSE); + globals.MenuStatus.Selected_Submenu=Submenu2_rs232_hardhand; call_new_submenu=YES; Submenu_Display(NO); break; - case mode_1bit: - IO_Setup_RS232(globals.Flash.baud, globals.Flash.parity, 1, globals.Flash.databits, globals.Flash.hardhand, globals.Flash.echo, FALSE); + case mode_57600: + IO_Setup_RS232(57600, globals.Flash.hardhand, FALSE); globals.MenuStatus.Selected_Submenu=Submenu2_rs232_hardhand; call_new_submenu=YES; Submenu_Display(NO); break; - case mode_2bits: - IO_Setup_RS232(globals.Flash.baud, globals.Flash.parity, 2, globals.Flash.databits, globals.Flash.hardhand, globals.Flash.echo, FALSE); + case mode_115200: + IO_Setup_RS232(115200, globals.Flash.hardhand, FALSE); globals.MenuStatus.Selected_Submenu=Submenu2_rs232_hardhand; call_new_submenu=YES; Submenu_Display(NO); break; + case mode_hand_hard: - IO_Setup_RS232(globals.Flash.baud, globals.Flash.parity, globals.Flash.stopbits, globals.Flash.databits, 1, globals.Flash.echo, FALSE); - globals.MenuStatus.Selected_Submenu=Submenu2_rs232_echo; + IO_Setup_RS232(globals.Flash.baud, 1, FALSE); + globals.MenuStatus.Selected_Submenu=Submenu1_setup; call_new_submenu=YES; Submenu_Display(NO); break; case mode_hand_off: - IO_Setup_RS232(globals.Flash.baud, globals.Flash.parity, globals.Flash.stopbits, globals.Flash.databits, 0, globals.Flash.echo, FALSE); - globals.MenuStatus.Selected_Submenu=Submenu2_rs232_echo; + IO_Setup_RS232(globals.Flash.baud, 0, FALSE); + globals.MenuStatus.Selected_Submenu=Submenu1_setup; call_new_submenu=YES; Submenu_Display(NO); break; - case mode_echo_on: - IO_Setup_RS232(globals.Flash.baud, globals.Flash.parity, globals.Flash.stopbits, globals.Flash.databits, globals.Flash.hardhand, 1, TRUE); - globals.MenuStatus.Selected_Submenu=Submenu1_setup; - break; - case mode_echo_off: - IO_Setup_RS232(globals.Flash.baud, globals.Flash.parity, globals.Flash.stopbits, globals.Flash.databits, globals.Flash.hardhand, 0, TRUE); - globals.MenuStatus.Selected_Submenu=Submenu1_setup; - break; } Main_update_shift_registers(); /* update values in pulse generator circuit */ if (call_new_submenu==NO) { - globals.Changes.update_whole_main_menu=YES; - Menu_Update_Display(); + Show_Main_Menu(); } /* re-run error_check to update min/max values based on actual settings, not proposed settings */ @@ -1,6 +1,6 @@ #include <glib.h> -void Menu_Refresh(); -void Menu_Update_Display(void); +void Update_Main_Menu_If_Visible(void); +void Show_Main_Menu(void); void Menu_Clear_Buttons(void); void Menu_Check_Buttons(void); @@ -4,7 +4,6 @@ #include "lcd.h" #include "monitor.h" #include "error_utils.h" -#include "dummy_functions.h" #include "menus.h" #include <glib.h> @@ -153,8 +152,6 @@ int I2C_Get_Monitor_Word(int channel) } - -int I2C_Check_Monitors(void); int I2C_Check_Monitors(void) { int monitor_word; @@ -243,7 +240,7 @@ int I2C_Check_Monitors(void) } if (update_display) { - Menu_Update_Display(); + Show_Main_Menu(); } return OK; @@ -14,7 +14,6 @@ END DESCRIPTION **********************************************************/ #include "flash.h" #include "nicutils.h" #include "version.h" -#include "dummy_functions.h" #include "i2c.h" #include "lcd.h" #include "menus.h" @@ -36,7 +35,6 @@ static int process_int_param (char *parameter, int *value, int item_count, int * static int process_int_range (char *parameter, int *value, int min_val, int max_val); static int process_on_off (char *parameter, int *value); static int process_two_ints (char *parameter, int *value, int min, int max); -static int process_four_ints (char *parameter, int *value, int v1, int v2, int v3, int v4); static int check_channel_ok (int channel, int enabled_channels, char chankey); static int Parser_id_word(char *id_me, int *channel, int *with_id_code); @@ -91,11 +89,7 @@ static int Go_zout_20(gchar** response, int channel, char *parameter,char *units static int Go_prot_trip_21(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_gpib_addr_59(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_ser_baud_60(gchar** response, int channel, char *parameter,char *units,int command_type); -static int Go_ser_par_61(gchar** response, int channel, char *parameter,char *units,int command_type); -static int Go_ser_bits_62(gchar** response, int channel, char *parameter,char *units,int command_type); -static int Go_ser_sbits_63(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_ser_rts_64(gchar** response, int channel, char *parameter,char *units,int command_type); -static int Go_ser_echo_65(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_load_68(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_meas_ampl_69(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_rst_6(gchar** response, int channel, char *parameter,char *units,int command_type); @@ -122,7 +116,6 @@ static int Go_avrq_ampl(gchar** response, int channel, char *parameter,char *uni static int Go_cal_100(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_cal_interval_101(gchar** response, int channel, char *parameter,char *units,int command_type); static int Go_eprom_reset_102(gchar** response, int channel, char *parameter,char *units,int command_type); -static int Go_broadcast_103(gchar** response, int channel, char *parameter,char *units,int command_type); static int Parser_id_word(char *id_me, int *channel, int *with_id_code) { @@ -144,7 +137,9 @@ static int Parser_id_word(char *id_me, int *channel, int *with_id_code) } - if (!strcmp(id_me,"*cls") ) { + if (!strcmp(id_me,"") ) { + id_code = 0; + } else if (!strcmp(id_me,"*cls") ) { id_code = 1; } else if (!strcmp(id_me,"*ese") ) { id_code = 2; @@ -356,8 +351,6 @@ static int Parser_id_word(char *id_me, int *channel, int *with_id_code) id_code = 107; } else if (!strcmp(id_me,"reset") || !strcmp(id_me,"res")) { id_code = 108; - } else if (!strcmp(id_me,"broadcast") ) { //FIXME - id_code = 109; } else { id_code = 9999; } @@ -441,11 +434,11 @@ static int Parser_find_commands(int commands[], int command_depth) {23,67,45}, /* diag:test:delay - 58 */ {13,68,70,69}, /* syst:comm:gpib:addr - 59 */ {13,68,71,72|optional,73}, /* syst:comm:ser:rec:baud - 60 */ - {13,68,71,72|optional,74,75|optional}, /* syst:comm:ser:rec:parity - 61 */ - {13,68,71,72|optional,76}, /* syst:comm:ser:rec:bits - 62 */ - {13,68,71,72|optional,77}, /* syst:comm:ser:rec:sbits - 63 */ + {13,68,71,72|optional,74,75|optional}, /* syst:comm:ser:rec:parity - 61 - not used */ + {13,68,71,72|optional,76}, /* syst:comm:ser:rec:bits - 62 - not used */ + {13,68,71,72|optional,77}, /* syst:comm:ser:rec:sbits - 63 - not used */ {13,68,71,80,79}, /* syst:comm:ser:control:rts - 64 */ - {13,68,71,72|optional,78}, /* syst:comm:ser:rec:echo - 65 */ + {13,68,71,72|optional,78}, /* syst:comm:ser:rec:echo - 65 - not used */ {13,14,82}, /* syst:err:count - 66 */ {28|optional,40,65,30}, /* sour:puls:gate:level - 67 */ {24,85}, /* output:load - 68 */ @@ -483,7 +476,6 @@ static int Parser_find_commands(int commands[], int command_depth) {88,107|optional}, /* calibration:all - 100 */ {88,37}, /* calibration:frequency - 101 */ {23,57,108}, /* diag:eprom:reset - 102 */ - {109} /* broadcast - 103 */ }; @@ -596,12 +588,10 @@ static int Parser_get_unit(char **parameter, char **units) static gchar* regex_replace (gchar* in_string, gchar* regex_string, gchar* replace_with) { - GRegex *regex = g_regex_new (regex_string, 0, 0, NULL); - gchar *out = g_regex_replace_literal (regex, in_string, -1, 0, replace_with, 0, NULL); - g_regex_unref (regex); - return out; + return conditional_regex_replace (TRUE, in_string, regex_string, replace_with); } + static gchar* filter_input (gchar *raw_in) { g_strstrip (raw_in); @@ -636,6 +626,9 @@ static gchar* filter_input (gchar *raw_in) void Parser_main (char *raw_in, int interactive_terminal, void(*cbfunc)(gpointer, gchar *), gpointer user_data) { + static GStaticMutex mutex = G_STATIC_MUTEX_INIT; + g_static_mutex_lock (&mutex); + int in_pos; /* this identifies the single character of in being processed */ int command_depth; /* how many command words have been parsed */ int old_command_depth; /* save this if in case of a compound message */ @@ -652,7 +645,6 @@ void Parser_main (char *raw_in, int interactive_terminal, void(*cbfunc)(gpointer int compound_message; /* this indicates that at least one semicolon has been found, so */ /* the message is a compound one */ - int is_query; int command_type; /* combination of is_query, parameter_found, and units_found */ @@ -788,6 +780,10 @@ void Parser_main (char *raw_in, int interactive_terminal, void(*cbfunc)(gpointer units_found = Parser_get_unit(¶meter,&units); + if (!globals.Sys.startup_complete) { + error_num=Startup_Not_Finished; + } + if (!error_num) { command_type=(is_query<<2) | (parameter_found?2:0) | units_found; @@ -943,21 +939,9 @@ void Parser_main (char *raw_in, int interactive_terminal, void(*cbfunc)(gpointer case 60: error_num=Go_ser_baud_60(&response,channel,parameter,units,command_type); break; - case 61: - error_num=Go_ser_par_61(&response,channel,parameter,units,command_type); - break; - case 62: - error_num=Go_ser_bits_62(&response,channel,parameter,units,command_type); - break; - case 63: - error_num=Go_ser_sbits_63(&response,channel,parameter,units,command_type); - break; case 64: error_num=Go_ser_rts_64(&response,channel,parameter,units,command_type); break; - case 65: - error_num=Go_ser_echo_65(&response,channel,parameter,units,command_type); - break; case 66: error_num=Go_syst_errcnt66(&response,channel,parameter,units,command_type); break; @@ -1060,9 +1044,6 @@ void Parser_main (char *raw_in, int interactive_terminal, void(*cbfunc)(gpointer case 102: error_num=Go_eprom_reset_102(&response,channel,parameter,units,command_type); break; - case 103: - error_num=Go_broadcast_103(&response,channel,parameter,units,command_type); - break; case 9999: // was only whitespace, ignore @@ -1080,10 +1061,8 @@ void Parser_main (char *raw_in, int interactive_terminal, void(*cbfunc)(gpointer if (interactive_terminal) { (*cbfunc)(user_data, error_response); } - } else { - if (interactive_terminal) { - (*cbfunc)(user_data, response); - } + } else if (response != NULL) { + (*cbfunc)(user_data, response); } g_free (units); @@ -1100,9 +1079,8 @@ void Parser_main (char *raw_in, int interactive_terminal, void(*cbfunc)(gpointer /* update display if it wasn't a query, and if the control menu isn't on (this gives the user a chance to press "Go To Local" to override control */ - if (!is_query && !(globals.MenuStatus.Selected_Submenu==Submenu1_rem_loc && globals.MenuStatus.Type_Of_Menu==Submenu_On)) { - Menu_Update_Display(); + Show_Main_Menu(); } /* re-run error_check to update min/max values based on actual settings, not proposed settings */ @@ -1114,6 +1092,8 @@ void Parser_main (char *raw_in, int interactive_terminal, void(*cbfunc)(gpointer } g_free (in); + + g_static_mutex_unlock (&mutex); } @@ -1209,7 +1189,7 @@ static int Go_Str_eprom_47(gchar** response, int channel, char *loc_string,char if (store_string[i]=='~') { store_string[i]=' '; } - *(char *)(&globals.Flash.flash_start + eprom_loc+i)=store_string[i]; + *(char *)(&globals.Flash.flash_start + eprom_loc+i)=g_ascii_toupper(store_string[i]); } *(char *)(&globals.Flash.flash_start + eprom_loc + i)=(char) 0; /* end of string */ writeUserBlock(&globals.Flash, eprom_loc, strlen(store_string)+1); @@ -1405,8 +1385,6 @@ static int Handle_Units(float *mult,char *units, char *in_base) base = g_strdup ("%"); prefix[len_all - 1] = 0; } else if (strcmp(prefix+pos,base)) { - g_free (base); - g_free (prefix); errornum = UnknownUnits; } else { prefix[pos]=0; @@ -1621,12 +1599,6 @@ static int process_two_ints (char *parameter, int *value, int min, int max) return process_int_param (parameter, value, 2, valid_choices, NO_ON_OFF); } -static int process_four_ints (char *parameter, int *value, int v1, int v2, int v3, int v4) -{ - int valid_choices[4] = {v1, v2, v3, v4}; - return process_int_param (parameter, value, 4, valid_choices, NO_ON_OFF); -} - static int check_channel_ok (int channel, int enabled_channels, char chankey) { /* how many channels overall */ @@ -2239,6 +2211,7 @@ static int Go_trig_source46(gchar** response, int channel, char *parameter,char } else { return SyntaxError; } + return OK; break; case query_simple: @@ -2362,7 +2335,8 @@ static int Go_delay_test58(gchar** response, int channel, char *parameter,char * return status; } globals.ChannelState[channel].test_delay_mode=on_off; - return Set_Mux(channel); + Set_Mux(channel); + return OK; break; default: @@ -2511,7 +2485,7 @@ static int Go_stb_8(gchar** response, int channel, char *parameter,char *units,i { switch (command_type) { case query_simple: - return query_int (response, GPIB_get_STB()); + return query_int (response, GPIB_and_VXI_get_STB()); break; default: @@ -2737,16 +2711,14 @@ static int Go_gpib_addr_59(gchar** response, int channel, char *parameter,char * static int Go_ser_baud_60(gchar** response, int channel, char *parameter,char *units,int command_type) { int new_baud, status; - int valid_choices[] = {1200, 2400, 4800, 9600}; + int valid_choices[] = {1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200}; switch (command_type) { case command_withparam: - // FIXME - expand this list - // FIXME - hardcoded "4" - if (status = process_int_param (parameter, &new_baud, 4, valid_choices, NO_ON_OFF)) { + if (status = process_int_param (parameter, &new_baud, 8, valid_choices, NO_ON_OFF)) { return status; } - return IO_Setup_RS232(new_baud, globals.Flash.parity, globals.Flash.stopbits, globals.Flash.databits, globals.Flash.hardhand, globals.Flash.echo, TRUE); + return IO_Setup_RS232(new_baud, globals.Flash.hardhand, TRUE); break; case query_simple: @@ -2754,110 +2726,7 @@ static int Go_ser_baud_60(gchar** response, int channel, char *parameter,char *u break; case query_param: - // FIXME - extract min, max from a new baud list - return query_min_max_int (response, parameter, 1200, 9600); - break; - - default: - return SyntaxError; - break; - } - - return ThisShouldntHappen; -} - - -static int Go_ser_par_61(gchar** response, int channel, char *parameter,char *units,int command_type) -{ - - int new_parity; - - switch (command_type) { - case command_withparam: - if (!strcmp(parameter,"even")) { - new_parity = rs232_parity_even; - } else if (!strcmp(parameter,"odd")) { - new_parity = rs232_parity_odd; - } else if (!strcmp(parameter,"none")) { - new_parity = rs232_parity_none; - } else { - return IllegalParameter; - } - - return IO_Setup_RS232(globals.Flash.baud, (char) new_parity, globals.Flash.stopbits, globals.Flash.databits, globals.Flash.hardhand, globals.Flash.echo, TRUE); - break; - - case query_simple: - if (globals.Flash.parity==rs232_parity_even) { - return query_string(response, "EVEN"); - } else if (globals.Flash.parity==rs232_parity_odd) { - return query_string(response, "ODD"); - } else if (globals.Flash.parity==rs232_parity_none) { - return query_string(response, "NONE"); - } - return OK; - break; - - default: - return SyntaxError; - break; - } - - return ThisShouldntHappen; -} - - -static int Go_ser_bits_62(gchar** response, int channel, char *parameter,char *units,int command_type) -{ - int new_databits; - int status; - - switch (command_type) { - case command_withparam: - if (status=process_two_ints (parameter, &new_databits, 7, 8)) { - return status; - } - - return IO_Setup_RS232(globals.Flash.baud, globals.Flash.parity, globals.Flash.stopbits, (char) new_databits, globals.Flash.hardhand, globals.Flash.echo, TRUE); - break; - - case query_simple: - return query_int (response, globals.Flash.databits); - break; - - case query_param: - return query_min_max_int (response, parameter, 7, 8); - break; - - default: - return SyntaxError; - break; - } - - return ThisShouldntHappen; -} - - -static int Go_ser_sbits_63(gchar** response, int channel, char *parameter,char *units,int command_type) -{ - int new_stopbits; - int status; - - switch (command_type) { - case command_withparam: - if (status=process_two_ints (parameter, &new_stopbits, 1, 2)) { - return status; - } - - return IO_Setup_RS232(globals.Flash.baud, globals.Flash.parity, (char) new_stopbits, globals.Flash.databits, globals.Flash.hardhand, globals.Flash.echo, TRUE); - break; - - case query_simple: - return query_int (response, globals.Flash.stopbits); - break; - - case query_param: - return query_min_max_int (response, parameter, 1, 2); + return query_min_max_int (response, parameter, 1200, 115200); break; default: @@ -2880,22 +2749,18 @@ static int Go_ser_rts_64(gchar** response, int channel, char *parameter,char *un // these are valid hardware handshake modes new_hardhand = 1; } else if (!strcmp(parameter,"on")) { - // FIXME - confusing: in absence of handware handshaking, - // RTS is supposed to be always ON? Confirm new_hardhand = 0; } else { return IllegalParameter; } - return IO_Setup_RS232(globals.Flash.baud, globals.Flash.parity, globals.Flash.stopbits, globals.Flash.databits, new_hardhand, globals.Flash.echo, TRUE); + return IO_Setup_RS232(globals.Flash.baud, new_hardhand, TRUE); break; case query_simple: if (globals.Flash.hardhand) { return query_string(response, "IBF"); } else { - // FIXME: confirm RTS is always high in BB ports if - // hardware handshaking is not used return query_string(response, "ON"); } return OK; @@ -2910,37 +2775,6 @@ static int Go_ser_rts_64(gchar** response, int channel, char *parameter,char *un } -static int Go_ser_echo_65(gchar** response, int channel, char *parameter,char *units,int command_type) -{ - int new_echo; - int status; - - switch (command_type) { - case command_withparam: - if (status=process_on_off (parameter, &new_echo)) { - return status; - } - return IO_Setup_RS232(globals.Flash.baud, globals.Flash.parity, globals.Flash.stopbits, globals.Flash.databits, globals.Flash.hardhand, (char) new_echo, TRUE); - break; - - case query_simple: - if (globals.Flash.echo) { - return query_int (response, 1); - } else { - return query_int (response, 0); - } - return OK; - break; - - default: - return SyntaxError; - break; - } - - return ThisShouldntHappen; -} - - static int Go_load_68(gchar** response, int channel, char *parameter,char *units,int command_type) { float new_load_type; @@ -3325,6 +3159,7 @@ static int Go_routeclose_78(gchar** response, int channel, char *parameter,char } else { Set_Route(channel,ROUTE_PRIMARY,temp1); Set_Route(channel,ROUTE_SECONDARY,temp2); + return OK; } break; @@ -3358,11 +3193,7 @@ static int Parse_chan_list(int channel,char *parameter,int *primary_selected, in int *value_pointer; #define PARSE_MAX_STRING 20 - char temp[PARSE_MAX_STRING+1]; - if (*response) { - *response[0]=0; - } if ( !(parameter[0]=='(' && parameter[1]=='@')) { return SyntaxError; @@ -3376,53 +3207,72 @@ static int Parse_chan_list(int channel,char *parameter,int *primary_selected, in return Route_Range_Error; } + pointer=1; do { + int error_num = OK; + pointer++; has_module_name = FALSE; /* get module name, if any */ + + GString *name = g_string_new (""); + for (i=0; isalpha(parameter[pointer]) && (i<PARSE_MAX_STRING); i++) { - temp[i]=parameter[pointer]; + name = g_string_append_c (name, parameter[pointer]); pointer++; } - temp[i]=0; value_pointer = primary_selected; if (i>0) { has_module_name = TRUE; - if (!strcmp (temp, "anod")) { + if (!strcmp (name->str, "anod")) { value_pointer = primary_selected; - } else if (!strcmp (temp, "cath")) { + } else if (!strcmp (name->str, "cath")) { if (globals.Flash.routing_required[channel]<2) { - return IllegalParameter; + error_num = IllegalParameter; } value_pointer = secondary_selected; } else { - return IllegalParameter; + error_num = IllegalParameter; } - if (parameter[pointer] == '(' ) { + if (!error_num && (parameter[pointer] == '(' )) { pointer++; } else { - return SyntaxError; + error_num =SyntaxError; } + } + g_string_free (name, TRUE); + + if (error_num) { + return error_num; + } + + GString *digits = g_string_new (""); + /* get digits */ for (i=0; isdigit(parameter[pointer]) && (i<PARSE_MAX_STRING); i++) { - temp[i]=parameter[pointer]; + digits = g_string_append_c (digits, parameter[pointer]); pointer++; } - temp[i]=0; if (i==0) { - return SyntaxError; + error_num = SyntaxError; + } + + n = atoi(digits->str); + g_string_free (digits, TRUE); + + if (error_num) { + return error_num; } - n = atoi(temp); if ((n < 1) || (n > globals.Flash.routing_max_pins[channel])) { return OutOfRange; } @@ -3436,11 +3286,11 @@ static int Parse_chan_list(int channel,char *parameter,int *primary_selected, in } /* query or command? */ - if (*response) { + if (response) { if (*value_pointer == n) { - strcat(*response,"1 "); + *response = g_strdup ("1 "); } else { - strcat(*response,"0 "); + *response = g_strdup ("0 "); } } else { if (value_pointer) { @@ -3770,8 +3620,41 @@ static int Go_puls_sep_89(gchar** response, int channel, char *parameter,char *u static int Go_sys_pwd_92(gchar** response, int channel, char *parameter,int command_type) { - // FIXME - needs /etc/shadow - return SyntaxError; + gchar *old_password = NULL; + gchar *new_password = NULL; + char *new_loc; + int error_num; + + switch (command_type) { + case command_withparam: + /* new password follows comma */ + + new_loc = strchr(parameter,','); + if (new_loc == NULL) { + return password_change_error; + } + + new_password = g_strdup_printf ("%s", new_loc + 1); + new_loc[0]=0; + old_password = g_strdup (parameter); + + error_num = OK; + if ((strlen(new_password)< 6) || (strlen(new_password)>32)) { + error_num = password_change_error; + } + + if (!error_num) { + error_num = change_password (old_password, new_password); + } + + g_free (new_password); + g_free (old_password); + return error_num; + + default: + return SyntaxError; + break; + } } @@ -4098,7 +3981,8 @@ static int Go_cal_100(gchar** response, int channel, char *parameter,char *units case query_simple: status = do_full_self_cal(&caldata); if (!no_report) { - query_string(response, caldata.response); + query_string(response, caldata.response->str); + g_string_free (caldata.response, TRUE); } return status; break; @@ -4145,38 +4029,3 @@ static int Go_cal_interval_101(gchar** response, int channel, char *parameter,ch return ThisShouldntHappen; } - - -static int Go_broadcast_103(gchar** response, int channel, char *parameter,char *units,int command_type) -{ -#ifdef DEBUG_ON - - gchar *broadcast_str = NULL; - - switch (command_type) { - case command_withparam: - broadcast_str = g_strdup_printf ("broadcast msg: %s\r\n> ", parameter); - send_message(broadcast_str); - g_free (broadcast_str); - return OK; - break; - - case command_param_units: - broadcast_str = g_strdup_printf ("broadcast msg: %s %s\r\n> ", parameter, units); - send_message(broadcast_str); - g_free (broadcast_str); - return OK; - break; - - default: - return SyntaxError; - break; - } - - return ThisShouldntHappen; - -#else - - return Unrecognized; -#endif -} @@ -9,7 +9,6 @@ #include "globals.h" #include "string_utils.h" -#include "dummy_functions.h" #include "device-functions.h" /* types of input commands that can be parsed */ @@ -27,13 +27,10 @@ gboolean cbClientOutput(gpointer data, gpointer additional) } gpointer elem; - g_print_debug("Try pop\n"); //try to pop an element from the queue elem=g_async_queue_try_pop(queue); - g_print_debug("after pop\n"); if(elem) { char* buf = (char*)elem; - g_print_debug("Extracted %s\n", buf); gssize size = strlen(buf); gssize written = 0; @@ -98,6 +95,7 @@ static void writeOutput(GPollableOutputStream* stream, gchar* data) if (data==NULL) { terminated = g_strdup(""); } else if (!strlen(data)) { + // prompt generation terminated = g_strdup("\r\n> "); } else { terminated = g_strdup_printf ("%s\r\n", data); @@ -12,4 +12,5 @@ typedef struct _streamStruct { gboolean cbClientInput(gpointer data, gpointer additional); gboolean cbClientOutput(gpointer data, gpointer additional); void initSignals(guint *signal); -void responseCb(gpointer instance, GObject *arg1, gpointer user_data);
\ No newline at end of file +void responseCb(gpointer instance, GObject *arg1, gpointer user_data); + diff --git a/string_utils.c b/string_utils.c index bf17e50..77765d2 100644 --- a/string_utils.c +++ b/string_utils.c @@ -5,8 +5,6 @@ #include "globals.h" #include "string_utils.h" -#include "lcd.h" // FIXME - void Float_To_Text(int decimal_digits,float number_in, gchar ** text_out) { @@ -40,7 +38,7 @@ gboolean String_is_it_numeric(char *parameter) void String_Parameter_To_Text(float Float_To_Convert, int significant_digits, - char *start_string,char *units,char *LCD_string,int show_plus_sign) + char *start_string,char *units,gchar **LCD_string,int show_plus_sign, int width_of_column) { gchar *floating_val = NULL; gchar *unit_mult = NULL; /* units multiplier, eg. M, k, u */ @@ -49,23 +47,18 @@ void String_Parameter_To_Text(float Float_To_Convert, int significant_digits, /* is annoying. (e.g. 1.000 -> 0.999) */ /* Move the decimal with string manipulations instead. */ - strcpy(LCD_string,start_string); + GString *out_gstr = g_string_new (start_string); /* if significant_digits is zero, used the supplied integer rather than the floating number */ if (!significant_digits) { - gchar *out_val; - out_val = g_strdup_printf ("%d", (int) Float_To_Convert); - strcat(LCD_string,out_val); - g_free (out_val); + g_string_append_printf (out_gstr, "%d", (int) Float_To_Convert); } else { int i; int shift_decimal_by; /* if the exponent isn't a multiple of 3, the decimal point will be moved */ int decimal_location; /* where the decimal is in the number string */ int exponent_val; /* the exponent, in integer form */ - GString *out_gstr = g_string_new (""); - Float_To_Text(remote_digits_after_decimal,Float_To_Convert,&floating_val); /* -- COPY FIRST ONE OR TWO CHARACTERS -- */ @@ -125,29 +118,49 @@ void String_Parameter_To_Text(float Float_To_Convert, int significant_digits, /* put in the new decimal point */ out_gstr = g_string_append_c (out_gstr, '.'); + int space_left = width_of_column - strlen(out_gstr->str) - strlen (unit_mult) - strlen (units); + /* copy the rest of the digits */ - for (i=shift_decimal_by+1+decimal_location; digits_so_far<significant_digits; ++i) { + for (i=shift_decimal_by+1+decimal_location; (digits_so_far<significant_digits) && (space_left>0); ++i) { out_gstr = g_string_append_c (out_gstr, floating_val[i]); ++digits_so_far; + space_left = width_of_column - strlen(out_gstr->str) - strlen (unit_mult) - strlen (units); /* leave space for minus sign, decimal point, and extra digit on the end too */ } /* -- FINISH UP -- */ - strcat(LCD_string,out_gstr->str); - g_string_free (out_gstr, TRUE); /* -- CHECK FOR TERMINATING DECIMAL POINT -- */ - if (LCD_string[strlen(LCD_string)-1]=='.') { - LCD_string[strlen(LCD_string)-1]=0; + int len = strlen(out_gstr->str); + if (out_gstr->str[len-1]=='.') { + out_gstr = g_string_erase (out_gstr, len-1, 1); } - strcat(LCD_string,unit_mult); + out_gstr = g_string_append (out_gstr, unit_mult); } - strcat(LCD_string,units); + out_gstr = g_string_append (out_gstr, units); + *LCD_string = g_strdup (out_gstr->str); + + g_string_free (out_gstr, TRUE); g_free (floating_val); g_free (unit_mult); } + +gchar* conditional_regex_replace (gboolean do_it, gchar* in_string, gchar* regex_string, gchar* replace_with) +{ + gchar *out; + + if (do_it) { + GRegex *regex = g_regex_new (regex_string, 0, 0, NULL); + out = g_regex_replace_literal (regex, in_string, -1, 0, replace_with, 0, NULL); + g_regex_unref (regex); + } else { + out = g_strdup (in_string); + } + + return out; +} diff --git a/string_utils.h b/string_utils.h index 6aaa8a1..96c3583 100644 --- a/string_utils.h +++ b/string_utils.h @@ -6,6 +6,6 @@ void Float_To_Text(int decimal_digits,float number_in, gchar** text_out); gboolean String_is_it_numeric(char *parameter); void String_Parameter_To_Text(float Float_To_Convert, int significant_digits, - char *start_string,char *units,char *LCD_string,int show_plus_sign); - + char *start_string,char *units,gchar **LCD_string,int show_plus_sign, int width_of_column); +gchar* conditional_regex_replace (gboolean do_it, gchar* in_string, gchar* regex_string, gchar* replace_with); #endif @@ -1,2 +1,2 @@ -#define FW_VERSION "5.00" +#define FW_VERSION "5.01" #define SCPI_version "1996.0" @@ -0,0 +1,342 @@ +/* + * Please do not edit this file. + * It was generated using rpcgen. + */ + +#ifndef _VXI11_H_RPCGEN +#define _VXI11_H_RPCGEN + +#include <rpc/rpc.h> + + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef long Device_Link; + +enum Device_AddrFamily { + DEVICE_TCP = 0, + DEVICE_UDP = 1, +}; +typedef enum Device_AddrFamily Device_AddrFamily; + +typedef long Device_Flags; + +typedef long Device_ErrorCode; + +struct Device_Error { + Device_ErrorCode error; +}; +typedef struct Device_Error Device_Error; + +struct Create_LinkParms { + long clientId; + bool_t lockDevice; + u_long lock_timeout; + char *device; +}; +typedef struct Create_LinkParms Create_LinkParms; + +struct Create_LinkResp { + Device_ErrorCode error; + Device_Link lid; + u_short abortPort; + u_long maxRecvSize; +}; +typedef struct Create_LinkResp Create_LinkResp; + +struct Device_WriteParms { + Device_Link lid; + u_long io_timeout; + u_long lock_timeout; + Device_Flags flags; + struct { + u_int data_len; + char *data_val; + } data; +}; +typedef struct Device_WriteParms Device_WriteParms; + +struct Device_WriteResp { + Device_ErrorCode error; + u_long size; +}; +typedef struct Device_WriteResp Device_WriteResp; + +struct Device_ReadParms { + Device_Link lid; + u_long requestSize; + u_long io_timeout; + u_long lock_timeout; + Device_Flags flags; + char termChar; +}; +typedef struct Device_ReadParms Device_ReadParms; + +struct Device_ReadResp { + Device_ErrorCode error; + long reason; + struct { + u_int data_len; + char *data_val; + } data; +}; +typedef struct Device_ReadResp Device_ReadResp; + +struct Device_ReadStbResp { + Device_ErrorCode error; + u_char stb; +}; +typedef struct Device_ReadStbResp Device_ReadStbResp; + +struct Device_GenericParms { + Device_Link lid; + Device_Flags flags; + u_long lock_timeout; + u_long io_timeout; +}; +typedef struct Device_GenericParms Device_GenericParms; + +struct Device_RemoteFunc { + u_long hostAddr; + u_long hostPort; + u_long progNum; + u_long progVers; + Device_AddrFamily progFamily; +}; +typedef struct Device_RemoteFunc Device_RemoteFunc; + +struct Device_EnableSrqParms { + Device_Link lid; + bool_t enable; + struct { + u_int handle_len; + char *handle_val; + } handle; +}; +typedef struct Device_EnableSrqParms Device_EnableSrqParms; + +struct Device_LockParms { + Device_Link lid; + Device_Flags flags; + u_long lock_timeout; +}; +typedef struct Device_LockParms Device_LockParms; + +struct Device_DocmdParms { + Device_Link lid; + Device_Flags flags; + u_long io_timeout; + u_long lock_timeout; + long cmd; + bool_t network_order; + long datasize; + struct { + u_int data_in_len; + char *data_in_val; + } data_in; +}; +typedef struct Device_DocmdParms Device_DocmdParms; + +struct Device_DocmdResp { + Device_ErrorCode error; + struct { + u_int data_out_len; + char *data_out_val; + } data_out; +}; +typedef struct Device_DocmdResp Device_DocmdResp; + +struct Device_SrqParms { + struct { + u_int handle_len; + char *handle_val; + } handle; +}; +typedef struct Device_SrqParms Device_SrqParms; + +#define DEVICE_ASYNC 0x0607B0 +#define DEVICE_ASYNC_VERSION 1 + +#if defined(__STDC__) || defined(__cplusplus) +#define device_abort 1 +extern Device_Error * device_abort_1(Device_Link *, CLIENT *); +extern Device_Error * device_abort_1_svc(Device_Link *, struct svc_req *); +extern int device_async_1_freeresult (SVCXPRT *, xdrproc_t, caddr_t); + +#else /* K&R C */ +#define device_abort 1 +extern Device_Error * device_abort_1(); +extern Device_Error * device_abort_1_svc(); +extern int device_async_1_freeresult (); +#endif /* K&R C */ + +#define DEVICE_CORE 0x0607AF +#define DEVICE_CORE_VERSION 1 + +#if defined(__STDC__) || defined(__cplusplus) +#define create_link 10 +extern Create_LinkResp * create_link_1(Create_LinkParms *, CLIENT *); +extern Create_LinkResp * create_link_1_svc(Create_LinkParms *, struct svc_req *); +#define device_write 11 +extern Device_WriteResp * device_write_1(Device_WriteParms *, CLIENT *); +extern Device_WriteResp * device_write_1_svc(Device_WriteParms *, struct svc_req *); +#define device_read 12 +extern Device_ReadResp * device_read_1(Device_ReadParms *, CLIENT *); +extern Device_ReadResp * device_read_1_svc(Device_ReadParms *, struct svc_req *); +#define device_readstb 13 +extern Device_ReadStbResp * device_readstb_1(Device_GenericParms *, CLIENT *); +extern Device_ReadStbResp * device_readstb_1_svc(Device_GenericParms *, struct svc_req *); +#define device_trigger 14 +extern Device_Error * device_trigger_1(Device_GenericParms *, CLIENT *); +extern Device_Error * device_trigger_1_svc(Device_GenericParms *, struct svc_req *); +#define device_clear 15 +extern Device_Error * device_clear_1(Device_GenericParms *, CLIENT *); +extern Device_Error * device_clear_1_svc(Device_GenericParms *, struct svc_req *); +#define device_remote 16 +extern Device_Error * device_remote_1(Device_GenericParms *, CLIENT *); +extern Device_Error * device_remote_1_svc(Device_GenericParms *, struct svc_req *); +#define device_local 17 +extern Device_Error * device_local_1(Device_GenericParms *, CLIENT *); +extern Device_Error * device_local_1_svc(Device_GenericParms *, struct svc_req *); +#define device_lock 18 +extern Device_Error * device_lock_1(Device_LockParms *, CLIENT *); +extern Device_Error * device_lock_1_svc(Device_LockParms *, struct svc_req *); +#define device_unlock 19 +extern Device_Error * device_unlock_1(Device_Link *, CLIENT *); +extern Device_Error * device_unlock_1_svc(Device_Link *, struct svc_req *); +#define device_enable_srq 20 +extern Device_Error * device_enable_srq_1(Device_EnableSrqParms *, CLIENT *); +extern Device_Error * device_enable_srq_1_svc(Device_EnableSrqParms *, struct svc_req *); +#define device_docmd 22 +extern Device_DocmdResp * device_docmd_1(Device_DocmdParms *, CLIENT *); +extern Device_DocmdResp * device_docmd_1_svc(Device_DocmdParms *, struct svc_req *); +#define destroy_link 23 +extern Device_Error * destroy_link_1(Device_Link *, CLIENT *); +extern Device_Error * destroy_link_1_svc(Device_Link *, struct svc_req *); +#define create_intr_chan 25 +extern Device_Error * create_intr_chan_1(Device_RemoteFunc *, CLIENT *); +extern Device_Error * create_intr_chan_1_svc(Device_RemoteFunc *, struct svc_req *); +#define destroy_intr_chan 26 +extern Device_Error * destroy_intr_chan_1(void *, CLIENT *); +extern Device_Error * destroy_intr_chan_1_svc(void *, struct svc_req *); +extern int device_core_1_freeresult (SVCXPRT *, xdrproc_t, caddr_t); + +#else /* K&R C */ +#define create_link 10 +extern Create_LinkResp * create_link_1(); +extern Create_LinkResp * create_link_1_svc(); +#define device_write 11 +extern Device_WriteResp * device_write_1(); +extern Device_WriteResp * device_write_1_svc(); +#define device_read 12 +extern Device_ReadResp * device_read_1(); +extern Device_ReadResp * device_read_1_svc(); +#define device_readstb 13 +extern Device_ReadStbResp * device_readstb_1(); +extern Device_ReadStbResp * device_readstb_1_svc(); +#define device_trigger 14 +extern Device_Error * device_trigger_1(); +extern Device_Error * device_trigger_1_svc(); +#define device_clear 15 +extern Device_Error * device_clear_1(); +extern Device_Error * device_clear_1_svc(); +#define device_remote 16 +extern Device_Error * device_remote_1(); +extern Device_Error * device_remote_1_svc(); +#define device_local 17 +extern Device_Error * device_local_1(); +extern Device_Error * device_local_1_svc(); +#define device_lock 18 +extern Device_Error * device_lock_1(); +extern Device_Error * device_lock_1_svc(); +#define device_unlock 19 +extern Device_Error * device_unlock_1(); +extern Device_Error * device_unlock_1_svc(); +#define device_enable_srq 20 +extern Device_Error * device_enable_srq_1(); +extern Device_Error * device_enable_srq_1_svc(); +#define device_docmd 22 +extern Device_DocmdResp * device_docmd_1(); +extern Device_DocmdResp * device_docmd_1_svc(); +#define destroy_link 23 +extern Device_Error * destroy_link_1(); +extern Device_Error * destroy_link_1_svc(); +#define create_intr_chan 25 +extern Device_Error * create_intr_chan_1(); +extern Device_Error * create_intr_chan_1_svc(); +#define destroy_intr_chan 26 +extern Device_Error * destroy_intr_chan_1(); +extern Device_Error * destroy_intr_chan_1_svc(); +extern int device_core_1_freeresult (); +#endif /* K&R C */ + +#define DEVICE_INTR 0x0607B1 +#define DEVICE_INTR_VERSION 1 + +#if defined(__STDC__) || defined(__cplusplus) +#define device_intr_srq 30 +extern void * device_intr_srq_1(Device_SrqParms *, CLIENT *); +extern void * device_intr_srq_1_svc(Device_SrqParms *, struct svc_req *); +extern int device_intr_1_freeresult (SVCXPRT *, xdrproc_t, caddr_t); + +#else /* K&R C */ +#define device_intr_srq 30 +extern void * device_intr_srq_1(); +extern void * device_intr_srq_1_svc(); +extern int device_intr_1_freeresult (); +#endif /* K&R C */ + +/* the xdr functions */ + +#if defined(__STDC__) || defined(__cplusplus) +extern bool_t xdr_Device_Link (XDR *, Device_Link*); +extern bool_t xdr_Device_AddrFamily (XDR *, Device_AddrFamily*); +extern bool_t xdr_Device_Flags (XDR *, Device_Flags*); +extern bool_t xdr_Device_ErrorCode (XDR *, Device_ErrorCode*); +extern bool_t xdr_Device_Error (XDR *, Device_Error*); +extern bool_t xdr_Create_LinkParms (XDR *, Create_LinkParms*); +extern bool_t xdr_Create_LinkResp (XDR *, Create_LinkResp*); +extern bool_t xdr_Device_WriteParms (XDR *, Device_WriteParms*); +extern bool_t xdr_Device_WriteResp (XDR *, Device_WriteResp*); +extern bool_t xdr_Device_ReadParms (XDR *, Device_ReadParms*); +extern bool_t xdr_Device_ReadResp (XDR *, Device_ReadResp*); +extern bool_t xdr_Device_ReadStbResp (XDR *, Device_ReadStbResp*); +extern bool_t xdr_Device_GenericParms (XDR *, Device_GenericParms*); +extern bool_t xdr_Device_RemoteFunc (XDR *, Device_RemoteFunc*); +extern bool_t xdr_Device_EnableSrqParms (XDR *, Device_EnableSrqParms*); +extern bool_t xdr_Device_LockParms (XDR *, Device_LockParms*); +extern bool_t xdr_Device_DocmdParms (XDR *, Device_DocmdParms*); +extern bool_t xdr_Device_DocmdResp (XDR *, Device_DocmdResp*); +extern bool_t xdr_Device_SrqParms (XDR *, Device_SrqParms*); + +#else /* K&R C */ +extern bool_t xdr_Device_Link (); +extern bool_t xdr_Device_AddrFamily (); +extern bool_t xdr_Device_Flags (); +extern bool_t xdr_Device_ErrorCode (); +extern bool_t xdr_Device_Error (); +extern bool_t xdr_Create_LinkParms (); +extern bool_t xdr_Create_LinkResp (); +extern bool_t xdr_Device_WriteParms (); +extern bool_t xdr_Device_WriteResp (); +extern bool_t xdr_Device_ReadParms (); +extern bool_t xdr_Device_ReadResp (); +extern bool_t xdr_Device_ReadStbResp (); +extern bool_t xdr_Device_GenericParms (); +extern bool_t xdr_Device_RemoteFunc (); +extern bool_t xdr_Device_EnableSrqParms (); +extern bool_t xdr_Device_LockParms (); +extern bool_t xdr_Device_DocmdParms (); +extern bool_t xdr_Device_DocmdResp (); +extern bool_t xdr_Device_SrqParms (); + +#endif /* K&R C */ + +#ifdef __cplusplus +} +#endif + +#endif /* !_VXI11_H_RPCGEN */ diff --git a/vxi11_clnt.c b/vxi11_clnt.c new file mode 120000 index 0000000..320589b --- /dev/null +++ b/vxi11_clnt.c @@ -0,0 +1 @@ +libvxi11client/vxi11_clnt.c
\ No newline at end of file diff --git a/vxi11_server.c b/vxi11_server.c new file mode 100644 index 0000000..4c3a837 --- /dev/null +++ b/vxi11_server.c @@ -0,0 +1,400 @@ +#include "vxi11.h" +#include "globals.h" +#include "gpib.h" +#include "parser.h" +#include <stdio.h> +#include <rpc/rpc.h> +#include <stdbool.h> +#include <sys/socket.h> +#include <netinet/in.h> + +#define DEBUG + +#ifdef DEBUG +#include <stdlib.h> +#endif + +#define SIZEOFARRAY(a) (sizeof(a) / sizeof(a[0])) + +#define ERR_SYNTAXERROR 1 +#define ERR_DEVICENOTACCESSIBLE 3 +#define ERR_INVALIDLINKINDENTIFIER 4 +#define ERR_PARAMETERERROR 5 +#define ERR_CHANNELNOTESTABLISHED 6 +#define ERR_OPERATIONNOTSUPPORTED 8 +#define ERR_OUTOFRESOURCES 9 +#define ERR_DEVICELOCKEDBYANOTHERLINK 11 +#define ERR_NOLOCKHELDBYTHISLINK 12 +#define ERR_IOTIMEOUT 15 +#define ERR_IOERROR 17 +#define ERR_INVALIDADDRESS 21 +#define ERR_ABORT 23 +#define ERR_CHANNELALREADYESTABLISHED 29 + +static CLIENT* intclient = NULL; + +typedef struct { +} ActiveLink; + +static ActiveLink* links[MAX_SESSIONS] = { NULL }; + +static bool isValidLink(int linkid) { + return links[linkid] != NULL; +} + +static bool isLocked() { + return globals.VxiLocks.locked_network_server != NO_SERVER_LOCKED; +} + +static bool haveLock(int lid) { + return globals.VxiLocks.locked_network_server == lid; +} + +#define FLAG_WAITLOCK 1 + +// todo +static bool waitForLock(Device_Flags flags, long timeout) { + if (!(flags & FLAG_WAITLOCK)) + return false; + return false; +} + +static void lock(int lid) { + globals.VxiLocks.locked_network_server = lid; +} + +static void unlock() { + globals.VxiLocks.locked_network_server = NO_SERVER_LOCKED; +} + +Device_Error * +device_abort_1_svc(Device_Link *argp, struct svc_req *rqstp) { + static Device_Error result; +#ifdef DEBUG + printf("device_abort_1_svc()\n"); +#endif + if (!isValidLink(*argp)) + result.error = ERR_INVALIDLINKINDENTIFIER; + else { + result.error = 0; + } + return &result; +} + +Create_LinkResp * +create_link_1_svc(Create_LinkParms *argp, struct svc_req *rqstp) { + static Create_LinkResp result; +#ifdef DEBUG + printf("create_link_1_svc()\n"); +#endif + if (globals.Remote.vxi_connections == MAX_SESSIONS) { + result.error = ERR_OUTOFRESOURCES; + } + else { + if (argp->lockDevice && isLocked() && !waitForLock(FLAG_WAITLOCK, argp->lock_timeout)) { + result.error = ERR_DEVICELOCKEDBYANOTHERLINK; + } + else { + ActiveLink* link = malloc(sizeof(ActiveLink)); + if (link == NULL) { + result.error = ERR_OUTOFRESOURCES; + } + else { + + int linkid; + for (linkid = 0; linkid < SIZEOFARRAY(links); linkid++) { + if (links[linkid] == NULL) { + links[linkid] = link; + break; + } + } + + struct sockaddr_in sin; + socklen_t len = sizeof(sin); + getsockname(rqstp->rq_xprt->xp_sock, (struct sockaddr *) &sin, &len); + result.error = 0; + result.abortPort = ntohs(sin.sin_port); + result.lid = linkid; + globals.Remote.vxi_connections++; + + } + } + } + return &result; +} + +Device_WriteResp * +device_write_1_svc(Device_WriteParms *argp, struct svc_req *rqstp) { + static Device_WriteResp result; +#ifdef DEBUG + printf("device_write_1_svc()\n"); +#endif + if (!isValidLink(argp->lid)) + result.error = ERR_INVALIDLINKINDENTIFIER; + else { + if (isLocked() && !haveLock(argp->lid) && !waitForLock(argp->flags, argp->lock_timeout)) + result.error = ERR_DEVICELOCKEDBYANOTHERLINK; + else { +#ifdef DEBUG + printf("got %s on link %d\n", argp->data.data_val, argp->lid); +#endif + Parser_main(argp->data, 0, GPIB_and_VXI_start_query_response, NULL); + result.size = argp->data.data_len; + result.error = 0; + } + } + return &result; +} + +Device_ReadResp * +device_read_1_svc(Device_ReadParms *argp, struct svc_req *rqstp) { + static Device_ReadResp result; +#ifdef DEBUG + printf("device_read_1_svc()\n"); +#endif + if (!isValidLink(argp->lid)) + result.error = ERR_INVALIDLINKINDENTIFIER; + else if (isLocked() && !haveLock(argp->lid) && !waitForLock(argp->flags, argp->lock_timeout)) + result.error = ERR_DEVICELOCKEDBYANOTHERLINK; + else { + result.data.data_val = "HELLO!"; + result.data.data_len = 7; + result.error = 0; + result.reason = 0x4; + } + return &result; +} + +Device_ReadStbResp * +device_readstb_1_svc(Device_GenericParms *argp, struct svc_req *rqstp) { + static Device_ReadStbResp result; +#ifdef DEBUG + printf("device_readstb_1_svc()\n"); +#endif + if (!isValidLink(argp->lid)) + result.error = ERR_INVALIDLINKINDENTIFIER; + else if (isLocked() && !haveLock(argp->lid) && !waitForLock(argp->flags, argp->lock_timeout)) + result.error = ERR_DEVICELOCKEDBYANOTHERLINK; + else { + result.error = 0; + result.stb = GPIB_and_VXI_get_STB(); + } + return &result; +} + +Device_Error * +device_trigger_1_svc(Device_GenericParms *argp, struct svc_req *rqstp) { + static Device_Error result; +#ifdef DEBUG + printf("device_trigger_1_svc()\n"); +#endif + if (!isValidLink(argp->lid)) + result.error = ERR_INVALIDLINKINDENTIFIER; + else if (isLocked() && !haveLock(argp->lid) && !waitForLock(argp->flags, argp->lock_timeout)) + result.error = ERR_DEVICELOCKEDBYANOTHERLINK; + else { + result.error = 0; + } + return &result; +} + +Device_Error * +device_clear_1_svc(Device_GenericParms *argp, struct svc_req *rqstp) { + static Device_Error result; +#ifdef DEBUG + printf("device_clear_1_svc()\n"); +#endif + if (!isValidLink(argp->lid)) + result.error = ERR_INVALIDLINKINDENTIFIER; + else if (isLocked() && !haveLock(argp->lid) && !waitForLock(argp->flags, argp->lock_timeout)) + result.error = ERR_DEVICELOCKEDBYANOTHERLINK; + else { + result.error = 0; + } + return &result; +} + +Device_Error * +device_remote_1_svc(Device_GenericParms *argp, struct svc_req *rqstp) { + static Device_Error result; +#ifdef DEBUG + printf("device_remote_1_svc()\n"); +#endif + if (!isValidLink(argp->lid)) + result.error = ERR_INVALIDLINKINDENTIFIER; + else if (isLocked() && !haveLock(argp->lid) && !waitForLock(argp->flags, argp->lock_timeout)) + result.error = ERR_DEVICELOCKEDBYANOTHERLINK; + else { + if (isLocked() && !haveLock(argp->lid)) + result.error = ERR_DEVICELOCKEDBYANOTHERLINK; + else + result.error = 0; + } + return &result; +} + +Device_Error * +device_local_1_svc(Device_GenericParms *argp, struct svc_req *rqstp) { + static Device_Error result; +#ifdef DEBUG + printf("device_local_1_svc()\n"); +#endif + if (!isValidLink(argp->lid)) + result.error = ERR_INVALIDLINKINDENTIFIER; + else if (isLocked() && !haveLock(argp->lid) && !waitForLock(argp->flags, argp->lock_timeout)) + result.error = ERR_DEVICELOCKEDBYANOTHERLINK; + else { + if (isLocked() && !haveLock(argp->lid)) + result.error = ERR_DEVICELOCKEDBYANOTHERLINK; + else + result.error = 0; + } + return &result; +} + +Device_Error * +device_lock_1_svc(Device_LockParms *argp, struct svc_req *rqstp) { + static Device_Error result; +#ifdef DEBUG + printf("device_lock_1_svc()\n"); +#endif + if (!isValidLink(argp->lid)) + result.error = ERR_INVALIDLINKINDENTIFIER; + else { + if (isLocked(argp->lid)) { + result.error = ERR_DEVICELOCKEDBYANOTHERLINK; + if (haveLock(argp->lid)) { + // maybe do something here to warn about a device trying to lock multiple times? + } + } + else { + lock(argp->lid); + result.error = 0; + } + } + return &result; +} + +Device_Error * +device_unlock_1_svc(Device_Link *argp, struct svc_req *rqstp) { + static Device_Error result; +#ifdef DEBUG + printf("device_unlock_1_svc()\n"); +#endif + if (!isValidLink(*argp)) + result.error = ERR_INVALIDLINKINDENTIFIER; + else { + if (!isLocked(*argp) || !haveLock(*argp)) + result.error = ERR_NOLOCKHELDBYTHISLINK; + else { + result.error = 0; + unlock(); + } + } + return &result; +} + +Device_Error * +device_enable_srq_1_svc(Device_EnableSrqParms *argp, struct svc_req *rqstp) { + static Device_Error result; +#ifdef DEBUG + printf("device_enable_srq_1_svc()\n"); +#endif + if (!isValidLink(argp->lid)) + result.error = ERR_INVALIDLINKINDENTIFIER; + else { + result.error = 0; + } + return &result; +} + +Device_DocmdResp * +device_docmd_1_svc(Device_DocmdParms *argp, struct svc_req *rqstp) { + static Device_DocmdResp result; +#ifdef DEBUG + printf("device_docmd_1_svc()\n"); +#endif + if (!isValidLink(argp->lid)) + result.error = ERR_INVALIDLINKINDENTIFIER; + else if (isLocked() && !haveLock(argp->lid) && !waitForLock(argp->flags, argp->lock_timeout)) + result.error = ERR_DEVICELOCKEDBYANOTHERLINK; + else { + result.data_out.data_out_len = 0; + result.data_out.data_out_val = NULL; + result.error = ERR_OPERATIONNOTSUPPORTED; + } + return &result; +} + +Device_Error * +destroy_link_1_svc(Device_Link *argp, struct svc_req *rqstp) { + static Device_Error result; +#ifdef DEBUG + printf("destroy_link_1_svc()\n"); +#endif + int lid = *argp; + if (!isValidLink(lid)) + result.error = ERR_INVALIDLINKINDENTIFIER; + else { +#ifdef DEBUG + printf("link %d destroyed\n", lid); +#endif + free(links[lid]); + links[lid] = NULL; + } + + globals.Remote.vxi_connections--; + return &result; +} + +Device_Error * +create_intr_chan_1_svc(Device_RemoteFunc *argp, struct svc_req *rqstp) { + static Device_Error result; +#ifdef DEBUG + printf("create_intr_chan_1_svc()\n"); + char clientaddressstring[INET_ADDRSTRLEN]; + inet_ntop(AF_INET, &argp->hostAddr, clientaddressstring, sizeof(clientaddressstring)); + printf("Client %s is asking for an interrupt connection on port %u\n", clientaddressstring, argp->hostPort); +#endif + if (argp->progFamily != DEVICE_TCP || argp->progNum != DEVICE_INTR || argp->progVers != DEVICE_INTR_VERSION) + result.error = ERR_OPERATIONNOTSUPPORTED; + else if (intclient != NULL) { + result.error = ERR_CHANNELALREADYESTABLISHED; + } + else { + struct sockaddr_in clientaddr; + clientaddr.sin_family = AF_INET; + clientaddr.sin_port = htons(argp->hostPort); + clientaddr.sin_addr.s_addr = argp->hostAddr; + int sock = RPC_ANYSOCK; + CLIENT* clnt = clnttcp_create(&clientaddr, DEVICE_INTR, DEVICE_INTR_VERSION, &sock, 0, 0); + if (clnt == NULL) { +#ifdef DEBUG + printf("Couldn't create interrupt channel client\n"); +#endif + result.error = ERR_CHANNELNOTESTABLISHED; + } + else { + intclient = clnt; + result.error = 0; + } + } + return &result; +} + +Device_Error * +destroy_intr_chan_1_svc(void *argp, struct svc_req *rqstp) { + static Device_Error result; +#ifdef DEBUG + printf("destroy_intr_chan_1_svc()\n"); +#endif + if (intclient == NULL) { + result.error = ERR_CHANNELNOTESTABLISHED; + } + else { + intclient = NULL; + result.error = 0; + } + return &result; +} + diff --git a/vxi11_svc.c b/vxi11_svc.c new file mode 100644 index 0000000..edc4212 --- /dev/null +++ b/vxi11_svc.c @@ -0,0 +1,228 @@ +#include "vxi11.h" +#include <stdio.h> +#include <stdlib.h> +#include <rpc/pmap_clnt.h> +#include <string.h> +#include <memory.h> +#include <sys/socket.h> +#include <netinet/in.h> + +#ifndef SIG_PF +#define SIG_PF void(*)(int) +#endif + +static void device_async_1(struct svc_req *rqstp, register SVCXPRT *transp) { + union { + Device_Link device_abort_1_arg; + } argument; + char *result; + xdrproc_t _xdr_argument, _xdr_result; + char *(*local)(char *, struct svc_req *); + + switch (rqstp->rq_proc) { + case NULLPROC: + (void) svc_sendreply(transp, (xdrproc_t) xdr_void, (char *) NULL); + return; + + case device_abort: + _xdr_argument = (xdrproc_t) xdr_Device_Link; + _xdr_result = (xdrproc_t) xdr_Device_Error; + local = (char *(*)(char *, struct svc_req *)) device_abort_1_svc; + break; + + default: + svcerr_noproc(transp); + return; + } + memset((char *) &argument, 0, sizeof(argument)); + if (!svc_getargs(transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) { + svcerr_decode(transp); + return; + } + result = (*local)((char *) &argument, rqstp); + if (result != NULL && !svc_sendreply(transp, (xdrproc_t) _xdr_result, result)) { + svcerr_systemerr(transp); + } + if (!svc_freeargs(transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) { + fprintf(stderr, "%s", "unable to free arguments"); + exit(1); + } + return; +} + +static void device_core_1(struct svc_req *rqstp, register SVCXPRT *transp) { + union { + Create_LinkParms create_link_1_arg; + Device_WriteParms device_write_1_arg; + Device_ReadParms device_read_1_arg; + Device_GenericParms device_readstb_1_arg; + Device_GenericParms device_trigger_1_arg; + Device_GenericParms device_clear_1_arg; + Device_GenericParms device_remote_1_arg; + Device_GenericParms device_local_1_arg; + Device_LockParms device_lock_1_arg; + Device_Link device_unlock_1_arg; + Device_EnableSrqParms device_enable_srq_1_arg; + Device_DocmdParms device_docmd_1_arg; + Device_Link destroy_link_1_arg; + Device_RemoteFunc create_intr_chan_1_arg; + } argument; + char *result; + xdrproc_t _xdr_argument, _xdr_result; + char *(*local)(char *, struct svc_req *); + + switch (rqstp->rq_proc) { + case NULLPROC: + (void) svc_sendreply(transp, (xdrproc_t) xdr_void, (char *) NULL); + return; + + case create_link: + _xdr_argument = (xdrproc_t) xdr_Create_LinkParms; + _xdr_result = (xdrproc_t) xdr_Create_LinkResp; + local = (char *(*)(char *, struct svc_req *)) create_link_1_svc; + break; + + case device_write: + _xdr_argument = (xdrproc_t) xdr_Device_WriteParms; + _xdr_result = (xdrproc_t) xdr_Device_WriteResp; + local = (char *(*)(char *, struct svc_req *)) device_write_1_svc; + break; + + case device_read: + _xdr_argument = (xdrproc_t) xdr_Device_ReadParms; + _xdr_result = (xdrproc_t) xdr_Device_ReadResp; + local = (char *(*)(char *, struct svc_req *)) device_read_1_svc; + break; + + case device_readstb: + _xdr_argument = (xdrproc_t) xdr_Device_GenericParms; + _xdr_result = (xdrproc_t) xdr_Device_ReadStbResp; + local = (char *(*)(char *, struct svc_req *)) device_readstb_1_svc; + break; + + case device_trigger: + _xdr_argument = (xdrproc_t) xdr_Device_GenericParms; + _xdr_result = (xdrproc_t) xdr_Device_Error; + local = (char *(*)(char *, struct svc_req *)) device_trigger_1_svc; + break; + + case device_clear: + _xdr_argument = (xdrproc_t) xdr_Device_GenericParms; + _xdr_result = (xdrproc_t) xdr_Device_Error; + local = (char *(*)(char *, struct svc_req *)) device_clear_1_svc; + break; + + case device_remote: + _xdr_argument = (xdrproc_t) xdr_Device_GenericParms; + _xdr_result = (xdrproc_t) xdr_Device_Error; + local = (char *(*)(char *, struct svc_req *)) device_remote_1_svc; + break; + + case device_local: + _xdr_argument = (xdrproc_t) xdr_Device_GenericParms; + _xdr_result = (xdrproc_t) xdr_Device_Error; + local = (char *(*)(char *, struct svc_req *)) device_local_1_svc; + break; + + case device_lock: + _xdr_argument = (xdrproc_t) xdr_Device_LockParms; + _xdr_result = (xdrproc_t) xdr_Device_Error; + local = (char *(*)(char *, struct svc_req *)) device_lock_1_svc; + break; + + case device_unlock: + _xdr_argument = (xdrproc_t) xdr_Device_Link; + _xdr_result = (xdrproc_t) xdr_Device_Error; + local = (char *(*)(char *, struct svc_req *)) device_unlock_1_svc; + break; + + case device_enable_srq: + _xdr_argument = (xdrproc_t) xdr_Device_EnableSrqParms; + _xdr_result = (xdrproc_t) xdr_Device_Error; + local = (char *(*)(char *, struct svc_req *)) device_enable_srq_1_svc; + break; + + case device_docmd: + _xdr_argument = (xdrproc_t) xdr_Device_DocmdParms; + _xdr_result = (xdrproc_t) xdr_Device_DocmdResp; + local = (char *(*)(char *, struct svc_req *)) device_docmd_1_svc; + break; + + case destroy_link: + _xdr_argument = (xdrproc_t) xdr_Device_Link; + _xdr_result = (xdrproc_t) xdr_Device_Error; + local = (char *(*)(char *, struct svc_req *)) destroy_link_1_svc; + break; + + case create_intr_chan: + _xdr_argument = (xdrproc_t) xdr_Device_RemoteFunc; + _xdr_result = (xdrproc_t) xdr_Device_Error; + local = (char *(*)(char *, struct svc_req *)) create_intr_chan_1_svc; + break; + + case destroy_intr_chan: + _xdr_argument = (xdrproc_t) xdr_void; + _xdr_result = (xdrproc_t) xdr_Device_Error; + local = (char *(*)(char *, struct svc_req *)) destroy_intr_chan_1_svc; + break; + + default: + svcerr_noproc(transp); + return; + } + memset((char *) &argument, 0, sizeof(argument)); + if (!svc_getargs(transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) { + svcerr_decode(transp); + return; + } + result = (*local)((char *) &argument, rqstp); + if (result != NULL && !svc_sendreply(transp, (xdrproc_t) _xdr_result, result)) { + svcerr_systemerr(transp); + } + if (!svc_freeargs(transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) { + fprintf(stderr, "%s", "unable to free arguments"); + exit(1); + } + return; +} + +void vxi_main() { + + printf("VXI service started\n"); + + register SVCXPRT *transp; + + pmap_unset(DEVICE_ASYNC, DEVICE_ASYNC_VERSION); + pmap_unset(DEVICE_CORE, DEVICE_CORE_VERSION); + + transp = svcudp_create(RPC_ANYSOCK); + if (transp == NULL) { + fprintf(stderr, "%s", "cannot create udp service."); + exit(1); + } + if (!svc_register(transp, DEVICE_ASYNC, DEVICE_ASYNC_VERSION, device_async_1, IPPROTO_UDP)) { + fprintf(stderr, "%s", "unable to register (DEVICE_ASYNC, DEVICE_ASYNC_VERSION, udp)."); + exit(1); + } + if (!svc_register(transp, DEVICE_CORE, DEVICE_CORE_VERSION, device_core_1, IPPROTO_UDP)) { + fprintf(stderr, "%s", "unable to register (DEVICE_CORE, DEVICE_CORE_VERSION, udp)."); + exit(1); + } + + transp = svctcp_create(RPC_ANYSOCK, 0, 0); + if (transp == NULL) { + fprintf(stderr, "%s", "cannot create tcp service."); + exit(1); + } + if (!svc_register(transp, DEVICE_ASYNC, DEVICE_ASYNC_VERSION, device_async_1, IPPROTO_TCP)) { + fprintf(stderr, "%s", "unable to register (DEVICE_ASYNC, DEVICE_ASYNC_VERSION, tcp)."); + exit(1); + } + if (!svc_register(transp, DEVICE_CORE, DEVICE_CORE_VERSION, device_core_1, IPPROTO_TCP)) { + fprintf(stderr, "%s", "unable to register (DEVICE_CORE, DEVICE_CORE_VERSION, tcp)."); + exit(1); + } + + svc_run(); + fprintf(stderr, "%s", "svc_run returned"); +} diff --git a/vxi11_xdr.c b/vxi11_xdr.c new file mode 100644 index 0000000..29d9371 --- /dev/null +++ b/vxi11_xdr.c @@ -0,0 +1,462 @@ +/* + * Please do not edit this file. + * It was generated using rpcgen. + */ + +#include "vxi11.h" + +bool_t +xdr_Device_Link (XDR *xdrs, Device_Link *objp) +{ + register int32_t *buf; + + if (!xdr_long (xdrs, objp)) + return FALSE; + return TRUE; +} + +bool_t +xdr_Device_AddrFamily (XDR *xdrs, Device_AddrFamily *objp) +{ + register int32_t *buf; + + if (!xdr_enum (xdrs, (enum_t *) objp)) + return FALSE; + return TRUE; +} + +bool_t +xdr_Device_Flags (XDR *xdrs, Device_Flags *objp) +{ + register int32_t *buf; + + if (!xdr_long (xdrs, objp)) + return FALSE; + return TRUE; +} + +bool_t +xdr_Device_ErrorCode (XDR *xdrs, Device_ErrorCode *objp) +{ + register int32_t *buf; + + if (!xdr_long (xdrs, objp)) + return FALSE; + return TRUE; +} + +bool_t +xdr_Device_Error (XDR *xdrs, Device_Error *objp) +{ + register int32_t *buf; + + if (!xdr_Device_ErrorCode (xdrs, &objp->error)) + return FALSE; + return TRUE; +} + +bool_t +xdr_Create_LinkParms (XDR *xdrs, Create_LinkParms *objp) +{ + register int32_t *buf; + + + if (xdrs->x_op == XDR_ENCODE) { + buf = XDR_INLINE (xdrs, 3 * BYTES_PER_XDR_UNIT); + if (buf == NULL) { + if (!xdr_long (xdrs, &objp->clientId)) + return FALSE; + if (!xdr_bool (xdrs, &objp->lockDevice)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->lock_timeout)) + return FALSE; + + } else { + IXDR_PUT_LONG(buf, objp->clientId); + IXDR_PUT_BOOL(buf, objp->lockDevice); + IXDR_PUT_U_LONG(buf, objp->lock_timeout); + } + if (!xdr_string (xdrs, &objp->device, ~0)) + return FALSE; + return TRUE; + } else if (xdrs->x_op == XDR_DECODE) { + buf = XDR_INLINE (xdrs, 3 * BYTES_PER_XDR_UNIT); + if (buf == NULL) { + if (!xdr_long (xdrs, &objp->clientId)) + return FALSE; + if (!xdr_bool (xdrs, &objp->lockDevice)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->lock_timeout)) + return FALSE; + + } else { + objp->clientId = IXDR_GET_LONG(buf); + objp->lockDevice = IXDR_GET_BOOL(buf); + objp->lock_timeout = IXDR_GET_U_LONG(buf); + } + if (!xdr_string (xdrs, &objp->device, ~0)) + return FALSE; + return TRUE; + } + + if (!xdr_long (xdrs, &objp->clientId)) + return FALSE; + if (!xdr_bool (xdrs, &objp->lockDevice)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->lock_timeout)) + return FALSE; + if (!xdr_string (xdrs, &objp->device, ~0)) + return FALSE; + return TRUE; +} + +bool_t +xdr_Create_LinkResp (XDR *xdrs, Create_LinkResp *objp) +{ + register int32_t *buf; + + if (!xdr_Device_ErrorCode (xdrs, &objp->error)) + return FALSE; + if (!xdr_Device_Link (xdrs, &objp->lid)) + return FALSE; + if (!xdr_u_short (xdrs, &objp->abortPort)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->maxRecvSize)) + return FALSE; + return TRUE; +} + +bool_t +xdr_Device_WriteParms (XDR *xdrs, Device_WriteParms *objp) +{ + register int32_t *buf; + + if (!xdr_Device_Link (xdrs, &objp->lid)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->io_timeout)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->lock_timeout)) + return FALSE; + if (!xdr_Device_Flags (xdrs, &objp->flags)) + return FALSE; + if (!xdr_bytes (xdrs, (char **)&objp->data.data_val, (u_int *) &objp->data.data_len, ~0)) + return FALSE; + return TRUE; +} + +bool_t +xdr_Device_WriteResp (XDR *xdrs, Device_WriteResp *objp) +{ + register int32_t *buf; + + if (!xdr_Device_ErrorCode (xdrs, &objp->error)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->size)) + return FALSE; + return TRUE; +} + +bool_t +xdr_Device_ReadParms (XDR *xdrs, Device_ReadParms *objp) +{ + register int32_t *buf; + + + if (xdrs->x_op == XDR_ENCODE) { + if (!xdr_Device_Link (xdrs, &objp->lid)) + return FALSE; + buf = XDR_INLINE (xdrs, 3 * BYTES_PER_XDR_UNIT); + if (buf == NULL) { + if (!xdr_u_long (xdrs, &objp->requestSize)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->io_timeout)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->lock_timeout)) + return FALSE; + + } else { + IXDR_PUT_U_LONG(buf, objp->requestSize); + IXDR_PUT_U_LONG(buf, objp->io_timeout); + IXDR_PUT_U_LONG(buf, objp->lock_timeout); + } + if (!xdr_Device_Flags (xdrs, &objp->flags)) + return FALSE; + if (!xdr_char (xdrs, &objp->termChar)) + return FALSE; + return TRUE; + } else if (xdrs->x_op == XDR_DECODE) { + if (!xdr_Device_Link (xdrs, &objp->lid)) + return FALSE; + buf = XDR_INLINE (xdrs, 3 * BYTES_PER_XDR_UNIT); + if (buf == NULL) { + if (!xdr_u_long (xdrs, &objp->requestSize)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->io_timeout)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->lock_timeout)) + return FALSE; + + } else { + objp->requestSize = IXDR_GET_U_LONG(buf); + objp->io_timeout = IXDR_GET_U_LONG(buf); + objp->lock_timeout = IXDR_GET_U_LONG(buf); + } + if (!xdr_Device_Flags (xdrs, &objp->flags)) + return FALSE; + if (!xdr_char (xdrs, &objp->termChar)) + return FALSE; + return TRUE; + } + + if (!xdr_Device_Link (xdrs, &objp->lid)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->requestSize)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->io_timeout)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->lock_timeout)) + return FALSE; + if (!xdr_Device_Flags (xdrs, &objp->flags)) + return FALSE; + if (!xdr_char (xdrs, &objp->termChar)) + return FALSE; + return TRUE; +} + +bool_t +xdr_Device_ReadResp (XDR *xdrs, Device_ReadResp *objp) +{ + register int32_t *buf; + + if (!xdr_Device_ErrorCode (xdrs, &objp->error)) + return FALSE; + if (!xdr_long (xdrs, &objp->reason)) + return FALSE; + if (!xdr_bytes (xdrs, (char **)&objp->data.data_val, (u_int *) &objp->data.data_len, ~0)) + return FALSE; + return TRUE; +} + +bool_t +xdr_Device_ReadStbResp (XDR *xdrs, Device_ReadStbResp *objp) +{ + register int32_t *buf; + + if (!xdr_Device_ErrorCode (xdrs, &objp->error)) + return FALSE; + if (!xdr_u_char (xdrs, &objp->stb)) + return FALSE; + return TRUE; +} + +bool_t +xdr_Device_GenericParms (XDR *xdrs, Device_GenericParms *objp) +{ + register int32_t *buf; + + if (!xdr_Device_Link (xdrs, &objp->lid)) + return FALSE; + if (!xdr_Device_Flags (xdrs, &objp->flags)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->lock_timeout)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->io_timeout)) + return FALSE; + return TRUE; +} + +bool_t +xdr_Device_RemoteFunc (XDR *xdrs, Device_RemoteFunc *objp) +{ + register int32_t *buf; + + + if (xdrs->x_op == XDR_ENCODE) { + buf = XDR_INLINE (xdrs, 4 * BYTES_PER_XDR_UNIT); + if (buf == NULL) { + if (!xdr_u_long (xdrs, &objp->hostAddr)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->hostPort)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->progNum)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->progVers)) + return FALSE; + + } else { + IXDR_PUT_U_LONG(buf, objp->hostAddr); + IXDR_PUT_U_LONG(buf, objp->hostPort); + IXDR_PUT_U_LONG(buf, objp->progNum); + IXDR_PUT_U_LONG(buf, objp->progVers); + } + if (!xdr_Device_AddrFamily (xdrs, &objp->progFamily)) + return FALSE; + return TRUE; + } else if (xdrs->x_op == XDR_DECODE) { + buf = XDR_INLINE (xdrs, 4 * BYTES_PER_XDR_UNIT); + if (buf == NULL) { + if (!xdr_u_long (xdrs, &objp->hostAddr)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->hostPort)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->progNum)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->progVers)) + return FALSE; + + } else { + objp->hostAddr = IXDR_GET_U_LONG(buf); + objp->hostPort = IXDR_GET_U_LONG(buf); + objp->progNum = IXDR_GET_U_LONG(buf); + objp->progVers = IXDR_GET_U_LONG(buf); + } + if (!xdr_Device_AddrFamily (xdrs, &objp->progFamily)) + return FALSE; + return TRUE; + } + + if (!xdr_u_long (xdrs, &objp->hostAddr)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->hostPort)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->progNum)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->progVers)) + return FALSE; + if (!xdr_Device_AddrFamily (xdrs, &objp->progFamily)) + return FALSE; + return TRUE; +} + +bool_t +xdr_Device_EnableSrqParms (XDR *xdrs, Device_EnableSrqParms *objp) +{ + register int32_t *buf; + + if (!xdr_Device_Link (xdrs, &objp->lid)) + return FALSE; + if (!xdr_bool (xdrs, &objp->enable)) + return FALSE; + if (!xdr_bytes (xdrs, (char **)&objp->handle.handle_val, (u_int *) &objp->handle.handle_len, 40)) + return FALSE; + return TRUE; +} + +bool_t +xdr_Device_LockParms (XDR *xdrs, Device_LockParms *objp) +{ + register int32_t *buf; + + if (!xdr_Device_Link (xdrs, &objp->lid)) + return FALSE; + if (!xdr_Device_Flags (xdrs, &objp->flags)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->lock_timeout)) + return FALSE; + return TRUE; +} + +bool_t +xdr_Device_DocmdParms (XDR *xdrs, Device_DocmdParms *objp) +{ + register int32_t *buf; + + + if (xdrs->x_op == XDR_ENCODE) { + if (!xdr_Device_Link (xdrs, &objp->lid)) + return FALSE; + if (!xdr_Device_Flags (xdrs, &objp->flags)) + return FALSE; + buf = XDR_INLINE (xdrs, 5 * BYTES_PER_XDR_UNIT); + if (buf == NULL) { + if (!xdr_u_long (xdrs, &objp->io_timeout)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->lock_timeout)) + return FALSE; + if (!xdr_long (xdrs, &objp->cmd)) + return FALSE; + if (!xdr_bool (xdrs, &objp->network_order)) + return FALSE; + if (!xdr_long (xdrs, &objp->datasize)) + return FALSE; + + } else { + IXDR_PUT_U_LONG(buf, objp->io_timeout); + IXDR_PUT_U_LONG(buf, objp->lock_timeout); + IXDR_PUT_LONG(buf, objp->cmd); + IXDR_PUT_BOOL(buf, objp->network_order); + IXDR_PUT_LONG(buf, objp->datasize); + } + if (!xdr_bytes (xdrs, (char **)&objp->data_in.data_in_val, (u_int *) &objp->data_in.data_in_len, ~0)) + return FALSE; + return TRUE; + } else if (xdrs->x_op == XDR_DECODE) { + if (!xdr_Device_Link (xdrs, &objp->lid)) + return FALSE; + if (!xdr_Device_Flags (xdrs, &objp->flags)) + return FALSE; + buf = XDR_INLINE (xdrs, 5 * BYTES_PER_XDR_UNIT); + if (buf == NULL) { + if (!xdr_u_long (xdrs, &objp->io_timeout)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->lock_timeout)) + return FALSE; + if (!xdr_long (xdrs, &objp->cmd)) + return FALSE; + if (!xdr_bool (xdrs, &objp->network_order)) + return FALSE; + if (!xdr_long (xdrs, &objp->datasize)) + return FALSE; + + } else { + objp->io_timeout = IXDR_GET_U_LONG(buf); + objp->lock_timeout = IXDR_GET_U_LONG(buf); + objp->cmd = IXDR_GET_LONG(buf); + objp->network_order = IXDR_GET_BOOL(buf); + objp->datasize = IXDR_GET_LONG(buf); + } + if (!xdr_bytes (xdrs, (char **)&objp->data_in.data_in_val, (u_int *) &objp->data_in.data_in_len, ~0)) + return FALSE; + return TRUE; + } + + if (!xdr_Device_Link (xdrs, &objp->lid)) + return FALSE; + if (!xdr_Device_Flags (xdrs, &objp->flags)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->io_timeout)) + return FALSE; + if (!xdr_u_long (xdrs, &objp->lock_timeout)) + return FALSE; + if (!xdr_long (xdrs, &objp->cmd)) + return FALSE; + if (!xdr_bool (xdrs, &objp->network_order)) + return FALSE; + if (!xdr_long (xdrs, &objp->datasize)) + return FALSE; + if (!xdr_bytes (xdrs, (char **)&objp->data_in.data_in_val, (u_int *) &objp->data_in.data_in_len, ~0)) + return FALSE; + return TRUE; +} + +bool_t +xdr_Device_DocmdResp (XDR *xdrs, Device_DocmdResp *objp) +{ + register int32_t *buf; + + if (!xdr_Device_ErrorCode (xdrs, &objp->error)) + return FALSE; + if (!xdr_bytes (xdrs, (char **)&objp->data_out.data_out_val, (u_int *) &objp->data_out.data_out_len, ~0)) + return FALSE; + return TRUE; +} + +bool_t +xdr_Device_SrqParms (XDR *xdrs, Device_SrqParms *objp) +{ + register int32_t *buf; + + if (!xdr_bytes (xdrs, (char **)&objp->handle.handle_val, (u_int *) &objp->handle.handle_len, ~0)) + return FALSE; + return TRUE; +} |