summaryrefslogtreecommitdiff
path: root/device-functions.c
diff options
context:
space:
mode:
Diffstat (limited to 'device-functions.c')
-rw-r--r--device-functions.c386
1 files changed, 230 insertions, 156 deletions
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;
}
}
-