/************************************************************ 

	clear_param.c
	Z-World, 2001

	Resets the parameters of the RabbitLink board (stored on
	the second flash) to default values.

	To use this program, compile it to the RabbitLink board,
	run it, then reload the RabbitLink with the DOWNLOAD.BIN
	firmware image.
	
 ************************************************************/

#define CONTROL_PORT		4244
#define PROG_BAUD			115200
#define CONSOLE_BAUD		57600			// default console baud rate
#define MY_IP_ADDRESS	"10.10.1.100"
#define MY_NETMASK		"255.255.255.0"
#define MY_GATEWAY		"10.10.1.1"
#define MY_NAME			"RabbitLink"
#define SERIAL_ECHO		1

#define FS_FLASH
#define FS_NUM_BLOCKS	64

#memmap xmem
#use "dcrtcp.lib"
#use "md5.lib"
#use "http.lib"
#use "smtp.lib"
#use "FileSystem.lib"

typedef unsigned short int 	uint;
typedef unsigned long  int		ulong;
typedef unsigned int uint16;							

typedef struct {
	ulong	ip;
	ulong	netmask;
} DTPNetworkDescription;

#define MAIL_FROM_SIZE 51
#define MAIL_SERV_SIZE 51
typedef struct {
	char	top; // used to mark the top of the struct 
	char	name[40];
	char	passwd[16];
	uint	control_port;
	ulong prog_baud;
	ulong console_baud;
	char	consolepasswd[16];
	ulong	my_ip_addr;
	ulong	sin_mask;
	ulong gate_ip;
	char	echo;
	char  mail_from[MAIL_FROM_SIZE];
	char	mail_serv[MAIL_SERV_SIZE];
	DTPNetworkDescription acceptableips[10];
} DTPIdentification;

int GlobalStatus;

DTPIdentification main_id;
char NextBackupFile;
unsigned long BackupVersion;
int wd; /* watchdog timer */
int PollsPending; /* number of poll packets transmitted and not ACKed */

void InitAllState(void);
void dtp_backup_id(void);
void dtp_hash(char *data, int length, char *digest);

/******************************************************************************/

void dtp_hash(char *data, int length, char *digest)
{
	auto md5_state_t	md5_state;

	md5_init(&md5_state);
	md5_append(&md5_state, (md5_byte_t *)data, length);
	md5_finish(&md5_state, (md5_byte_t *)digest);
}

/******************************************************************************/

/*
 * This should be called to backup our identification + IP into flash
 */
void dtp_backup_id(void)
{
	auto int offset, len, retval;
	auto unsigned long temp;
	auto File f, *F;
	F = &f;
	
	main_id.top = 0xa5;
	main_id.my_ip_addr = my_ip_addr;
	main_id.sin_mask = sin_mask;
	main_id.gate_ip = _arp_gate_data[0].gate_ip;

	/* backup: main_id */
	printf("dtp_backup_id()...\n");
	if(fcreate(F, NextBackupFile)) {
		/* Error! File allready exists? */
		goto backup_error;
	}
	
	/* write out the new version number */
	BackupVersion++;
	printf("\tBackupVersion == %ld\n",BackupVersion);
	if(4 != fwrite(F, (char *)&BackupVersion, 4)) {
		goto backup_error;
	}
	
	/* write out the length of the config table */
	temp = sizeof(main_id);
	printf("\tsizeof(main_id) == %ld\n",temp);
	if(4 != fwrite(F, (char *)&temp, 4)) {
		goto backup_error;
	}

	/* write out the actual config table */
	offset = 0;
	len = sizeof(main_id);
	while(offset < len) {
		retval = fwrite(F, (char *)&(main_id.top) + offset, len - offset);
		if(retval < 1) {
			/* error - no room */
			goto backup_error;
		}
		offset += retval;
	}

	/* write out the length of the spec table */
	temp = SSPEC_MAXSPEC * sizeof(ServerSpec);
	printf("\tsizeof(ServerSpec[]) == %ld\n",temp);
	if(4 != fwrite(F, (char *)&temp, 4)) {
		goto backup_error;
	}

	/* write the actual spec table */
	offset = 0;
	len = SSPEC_MAXSPEC * sizeof(ServerSpec);
	while(offset < len) {
		retval = fwrite(F, (char *)&(server_spec[0]) + offset, len - offset);
		if(retval < 1) {
			/* error - no room */
			goto backup_error;
		}
		offset += retval;
	}

	fclose(F);
	/* remove the old file, if it exists */
	if(255 == NextBackupFile) {
		fdelete(254);
		NextBackupFile = 254;
	} else {
		fdelete(255);
		NextBackupFile = 255;
	}
	
	return;	

backup_error:
	fclose(F);
	
	/* should we format the fs here? */
	printf("ERROR: No room to backup config table in flash FS!\n");
	return; 
}

/******************************************************************************/

void InitAllState(void)
{
	/* init everything to basic values */
	BackupVersion = 1;
	NextBackupFile = 255;
	main_id.control_port = CONTROL_PORT;
	main_id.prog_baud = PROG_BAUD;
	main_id.console_baud = CONSOLE_BAUD;
	strcpy(main_id.name,MY_NAME);
	dtp_hash("",0,main_id.passwd);
	dtp_hash("",0,main_id.consolepasswd);
	main_id.echo = SERIAL_ECHO;
	strcpy(main_id.mail_from, "nobody@nowhere.com");
	strcpy(main_id.mail_serv, "10.10.6.1");
	smtp_setserver(main_id.mail_serv);
}

/******************************************************************************/

main()
{
	sock_init();

	/* reset it all! */
	InitAllState();
	sspec_init();
	fs_format(0, FS_NUM_BLOCKS, 1);

	/* backup the reset data to flash */		
	dtp_backup_id();

	printf("Parameters reset.\n");

	/* wait in an endless loop (instead of running over and over in run mode) */
	while (1)
		/* do nothing */;	
}
