[En-Nut-Discussion] changes inside the ip stack?

Gerd Mueller gmueller at netways.de
Fri May 27 18:22:40 CEST 2005


Hi list,

last year I wrote a simple application for the ethernut board (1.3). It
only enables or disables three dataports. Everything worked fine. But
now with the newest ethernut 3.9.6 the boards green led lights
constantly and nothing works :-(. Same for rs232 and tcps sample.
Basemon works. 

So are there any major changes? Can anybody help me?

Thank you

Gerd 



/*

 * Copyright (C) 2004 by Gerd Mueller - Netways GmbH. All rights reserverd
 * based on portdio from egnite Software GmbH (C)opyright  2001-2002
 *
 */
 
 /* $Id: tlight.c 421 2004-10-04 08:58:52Z gmueller $  */

#define MY_MAC       0x00,0x06,0x98,0x01,0x06,0x19
#define MY_IP        "192.168.192.100"
#define MY_MASK      "255.255.255.0"
#define TCPPORT  23
#define BAUD 9600

#define BUFFERSIZE 	128

#ifdef ETHERNUT2
#include <dev/lanc111.h>
#else
#include <dev/nicrtl.h>
#endif
#include <dev/uartavr.h>

#include <sys/version.h>
#include <sys/heap.h>
#include <sys/thread.h>
#include <sys/timer.h>
#include <sys/socket.h>

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <io.h>
#include <fcntl.h>

#include <arpa/inet.h>
#include <pro/dhcp.h>

#include <sys/confnet.h>
#include <avr/wdt.h>

#define PW_EE_OFFSET 512

typedef struct _PW_EE PW_EE;

struct _PW_EE  {
	u_char pw_size; 		// size of structur
	u_char pw_head[3];
	u_char pw[9];
};

PW_EE pw;

static char nbuff[128];


/*
 *  Help
 */
prog_char help_P[] = 
		    "\r\n"
       		"ip=#\tset IP to # - use 0.0.0.0 for dhcp (active after reboot!)\r\n"
        	"net=#\tset netmask to # (active after reboot!)\r\n"
        	"gw=#\tset default gateway to # (active after reboot!)\r\n"
        	"set=#\tSwitch bulbs on (e.g. 1=green, 2=yellow, 4=red, 5=red+green)\r\n"
			"pw=#\tset password to # (active after reconnect!)\r\n"
        	"cfg\tLists config\r\n"
        	"exit\tClose connection\r\n"
        	"\r\n";
prog_char internal_help_P[] = 
		    "\r\n"
        	"memory\tPrints free memory\r\n"
        	"reboot\tReboots TLight\r\n"
        	"threads\tLists all threads\r\n"
       		"timer\tLists all timer\r\n"
        	"\r\n";

/*
 * Status
 */
prog_char version_P[] = "TLight Version: $Id: tlight.c 421 2004-10-04 08:58:52Z gmueller $ \r\n";
prog_char nut_version_P[] = "Nut/OS-Version";

prog_char rebooting_P[] = "Please wait. I am rebooting ...\r\nr";
prog_char listen_to_P[] = "TLight listens to ";
prog_char conf_eth0_P[] = "Configure eth0...\r\n";
prog_char initial_boot_P[] = "initial boot...\r\n";
prog_char no_dhcp_P[] = "no DHCP...\r\n";
prog_char bulbcheck_P[] = "Checking bulbs.\r\n";
prog_char booting_P[] = "\r\nPlease wait while TLight is booting.\r\n";
prog_char done_P[] = "Bulbcheck has finished.\r\n";
   
        	
/*
 * Errors
 * */
prog_char pw_too_long_P[]     = "The password is too long. Please use maximal 8 chars.\r\n"; 
prog_char wrong_password_P[]  = "Wrong password!\r\nPassword: ";
prog_char too_many_digits_P[] = "Too many digits!\r\n";

/*
 * Information
 */
prog_char welcome_P[] = "Welcome to TLight. Type help to get help.\r\n# ";
prog_char password_P[] = "Please insert password (default is \"TLight\"): ";
prog_char goodby_P[] = "Goodbye\r\n";
prog_char ok_P[] = "Ok\r\n";
prog_char prompt_P[] = "# ";
prog_char threads_P[] = "List of threads with name,state,prio,stack,mem,timeout follows\r\n";
prog_char timer_P[] = "List of timers with ticks left and interval follows\r\n";

/*
 * Load Password from EEProm 
 */
int LoadPW(void) {
   eeprom_read_block(&pw,  (void *) PW_EE_OFFSET, sizeof(PW_EE)) ;
    if (strcmp(pw.pw_head,"pw") != 0)
    	strcpy(pw.pw,"TLight");
    return 0;
}


void print_ok(FILE * stream) {
	fputs_P(ok_P,stream);
}

void print_hex(FILE * stream,char * text,int max) {
	int i;
	for (i=0;i<max;i++) {
		fprintf(stream,"%02X ",text[i]);
	}
}

void set_dport(int mask) {
    outp(inp(PORTD) | mask, PORTD);
}

void reset_dport(int mask) {
    outp(inp(PORTD) & ~mask, PORTD);
}


/*
 * Store Password to EEProm 
 */
int SavePW(void)
{
    u_char *cp;
    size_t i;
  
    strcpy(pw.pw_head,"pw");
     
    pw.pw_size = sizeof(PW_EE);
    for (cp = (u_char *) &pw, i = 0; i < sizeof(PW_EE); cp++, i++)
        if(eeprom_read_byte((void *) (i + PW_EE_OFFSET)) != *cp)
            eeprom_write_byte((void *) (i + PW_EE_OFFSET), *cp);

    return 0;
}

/* 
 * Handle user input
 */
int  doit (char * buff, FILE * stream) {
    int rw=1;
	int done=0;
    int stat = -1;
    

	/*
	 * Reboot
	 */
	if (strlen(buff) > 1 && strncmp(buff, "reboot", strlen(buff)) == 0 && !done) {
	    fputs_P(rebooting_P,stream);
	    cli();
	    wdt_reset();
	    wdt_enable(1);
	    while(1);
	    done=1;
	}
	
	        /*
         * Memory info.
         */
        if (strlen(buff) > 1 && strncmp(buff, "internal", strlen(buff)) == 0 && !done ) {
			fputs_P(internal_help_P,stream);
            done=1;
        }
	        /*
         * Memory info.
         */
        if (strlen(buff) > 1 && strncmp(buff, "memory", strlen(buff)) == 0 && !done ) {
            fprintf(stream, "%u bytes RAM free\r\n", NutHeapAvailable());
            done=1;
        }

        /*
         * List threads.
         */
        if (strlen(buff) > 1 && strncmp(buff, "threads", strlen(buff)) == 0 && !done ) {
            NUTTHREADINFO *tdp;
            NUTTIMERINFO *tnp;

            fputs_P(threads_P, stream);
            for (tdp = nutThreadList; tdp; tdp = tdp->td_next) {
                fputs(tdp->td_name, stream);
                fputs("\t", stream);
                switch (tdp->td_state) {
                case TDS_TERM:
                    fputs("\tTerm\t", stream);
                    break;
                case TDS_RUNNING:
                    fputs("\tRun\t", stream);
                    break;
                case TDS_READY:
                    fputs("\tReady\t", stream);
                    break;
                case TDS_SLEEP:
                    fputs("\tSleep\t", stream);
                    break;
                }
                fprintf(stream, "%u\t%u", tdp->td_priority, (u_short) tdp->td_sp - (u_short) tdp->td_memory);
                if (*((u_long *) tdp->td_memory) != DEADBEEF)
                    fputs("\tCorrupted\t", stream);
                else
                    fputs("\tOK\t", stream);

                if ((tnp = (NUTTIMERINFO *) tdp->td_timer) != 0)
                    fprintf(stream, "%lu", tnp->tn_ticks_left);
                else
                    fputs("None", stream);
                fputs("\r\n", stream);
            }
            fputs("\r\n", stream);
            done=1;
        }

        /*
         * List timer.
         */
        if (strlen(buff) > 1 && strncmp(buff, "timers", strlen(buff)) == 0 && !done ) {
            NUTTIMERINFO *tnp;

            fputs_P(timer_P, stream);
            for (tnp = nutTimerList; tnp; tnp = tnp->tn_next) {
                fprintf(stream, "%lu", tnp->tn_ticks_left);
                if (tnp->tn_ticks)
                    fprintf(stream, "\t%lu\r\n", tnp->tn_ticks);
                else
                    fputs("\tOneshot\r\n", stream);
            }
            fputs("\r\n", stream);
            done=1;
        }
	
	
        /*
         * Exit.
         */
        if (strlen(buff) > 1 && (strncmp(buff, "exit", strlen(buff)) == 0 || strncmp(buff, "quit", strlen(buff)) == 0) && !done ) {
            stat = inp(PIND);
            fputs_P(goodby_P, stream);
            done=1;
	    	rw=0;
        }
	
        /*
         * Port status.
         */
        if (strlen(buff) > 1 && strncmp(buff, "query", strlen(buff)) == 0 && !done) {
            stat = inp(PIND);
            fprintf(stream, "%d (%02X)\r\n", stat, stat);
            done=1;
        }

        /*
         * Print version.
         */
        if (strlen(buff) > 1 && strncmp(buff, "version", strlen(buff)) == 0 && !done) {
            stat = inp(PIND);
            fputs_P(version_P,stream);
            fputs_P(nut_version_P,stream);
            fprintf(stream, "%s \r\n",NutVersionString());
            done=1;
        }
        /*
         * Prints the ipconfig
         */
        if (strlen(buff) > 1 && strncmp(buff, "cfg", strlen(buff)) == 0 && !done) {
        	fputs("\r\n",stream);
        	fprintf(stream, "mac:%02X-%02X-%02X-%02X-%02X-%02X\r\n",confnet.cdn_mac[0],confnet.cdn_mac[1],confnet.cdn_mac[2],confnet.cdn_mac[3],confnet.cdn_mac[4],confnet.cdn_mac[5]);
    		fprintf(stream, "ip: %s\r\n",inet_ntoa(confnet.cdn_ip_addr));
        	fprintf(stream, "cfg:%s\r\n",inet_ntoa(confnet.cdn_cip_addr));
    		fprintf(stream, "net:%s\r\n",inet_ntoa(confnet.cdn_ip_mask));
    		fprintf(stream, "gw: %s\r\n",inet_ntoa(confnet.cdn_gateway));
    		fprintf(stream, "pw: %s\r\n\r\n",pw.pw);
            done=1;
        }


        /*
         * Set TLights.
         */
        if (strlen(buff) > 1 && strncmp(buff, "set=", 4) == 0 && !done) {
	    	if(strlen(buff)-4>2) {
            	fputs_P(too_many_digits_P, stream);
	    	} else {
	    		int mask = atoi(buff +4);
	    		outp(inp(PORTD) & 0x00, PORTD);
            	outp(mask, PORTD);
            	print_ok(stream);
	    	}
            done=1;
        }

        /*
         * Change IP.
         */
        if (strlen(buff) > 1 && strncmp(buff, "ip=", 3) == 0 && !done) {
    		confnet.cdn_cip_addr = inet_addr (buff+3);
	    	NutNetSaveConfig();
            print_ok(stream);
            done=1;
        }
        /*
         * Change Netmask.
         */
        if (strlen(buff) > 1 && strncmp(buff, "net=", 4) == 0 && !done) {
	    confnet.cdn_ip_mask = inet_addr (buff+4);
	    NutNetSaveConfig();
            print_ok(stream);
            done=1;
        }
        /*
         * Change Gateway.
         */
        if (strlen(buff) > 1 && strncmp(buff, "gw=", 3) == 0 && !done) {
	    confnet.cdn_gateway = inet_addr (buff+3);
	    NutNetSaveConfig();
            print_ok(stream);
            done=1;
        }
        /*
         * Change password.
         */
        if (strlen(buff) > 1 && strncmp(buff, "pw=", 3) == 0 && !done) {
	    if(strlen(buff)-3<=8) {
	    	strcpy(pw.pw,buff+3);
	    	SavePW();
	    	print_ok(stream);
	    } else {
	    	fputs_P(pw_too_long_P,stream);
	    }
            done=1;
        }


	if(!done)  {
		fputs_P(help_P,stream);

	}
	
	//prompt  
	if(rw) fputs_P(prompt_P,stream);
	
	return rw;
}

/*
 * RS232 Thread - process seriell client requests.
 */
void rs232(void * arg) {
	FILE *stream=arg;
    u_char buff[BUFFERSIZE];
    u_char *cp;
    u_char chr;
    int got;
    int len;
    
	for(;;) {
 		fflush(stream);   
		chr=fgetc(stream);
		fprintf(stream,"%c",chr);

		len=strlen(buff);
    	if (len>=sizeof(buff))
    		break;
           		
		buff[len]=chr;
		buff[len+1]=0;

		if ((cp = strchr(buff, '\r')) != 0) {
			*cp = 0;
           	break;
		}
           	 	
       	if ((cp = strchr(buff, '\n')) != 0) {
        	*cp = 0;
            fputs_P(prompt_P,stream);
            break;
		}
        /*
         * Ignore blank lines.
         */
        got = strlen(buff);
        if (got == 0)
            continue;
            
		
	}
	    		
	if(doit(buff,stream)) {
		buff[0]=0;
		return;
	} else {
		buff[0]=0;
    	fputs_P(welcome_P, stream);
 		fflush(stream);   
	}
        
}


THREAD(Receiver, arg)
{
	FILE  * stream = arg;

  	//  NutThreadSetPriority(128); // seriell gets lower prio

    fputs_P(welcome_P, stream);
    fflush(stream);   
 	
    for (;;) {
        rs232(stream);
    }
    NutThreadYield();
}

/*
 * Process network client requests.
 */
void ProcessRequests(FILE * stream)
{
    int authenticated=0;
    int fails=0;

    u_char *cp;
    int got=0;
    
    //27Byte workaround :-(
    fgets(nbuff,28,stream);

    fputs_P(password_P, stream);

    for(;;) {
    	fflush(stream);
         
        if (fgets(nbuff, sizeof(nbuff), stream) == 0)
            break;
        if ((cp = strchr(nbuff, '\r')) != 0)
            *cp = 0;
        if ((cp = strchr(nbuff, '\n')) != 0)
            *cp = 0;
           
        /*
         * Ignore blank lines.
         */
        got = strlen(nbuff);
        
        if (got == 0) {
        	fputs_P(prompt_P,stream);
            continue;
        }
            
		if(!authenticated) {
			if (strncmp(pw.pw,nbuff, got)==0) {
				fputs_P(welcome_P,stream);
				authenticated=1;
			} else {
				if (++fails<4) {
					fputs_P(wrong_password_P,stream);
				} else {
					fputs_P(goodby_P,stream);
					break;
				}
			}
    	} else {
			if(!doit(nbuff,stream)) {
				break;
			}
		}
    }
}


/*
 * Init Port D
 */
void init_dio(FILE *uart)
{
	int stat;
	
    outp(0xff, DDRD);
    fputs_P(bulbcheck_P,uart);
    outp(inp(PORTD) & ~ 0xff, PORTD);
    
    
    outp(inp(PORTD) | 0x01, PORTD);
    
    outp(0x1,PORTD);
    fputs("[G--]\r",uart);
    NutSleep(1600);
    
    outp(0x2,PORTD);
    fputs("[-Y-]\r",uart);
    NutSleep(1600);
    
    outp(0x4,PORTD);
    fputs("[--R]\r",uart);  
    NutSleep(1600);

    outp(inp(PORTD) & ~ 0xff, PORTD);
    fputs_P(done_P,uart);
    
}

/*
 * Main application routine. 
 */
int main(void)
{
    TCPSOCKET *sock;
    u_long baud = BAUD;
    FILE * stream;
    FILE * uart;
    u_char mac[6] = { MY_MAC };
  
    NutRegisterDevice(&devUart0, 0, 0);
    NutRegisterDevice(&DEV_ETHER, 0x8300, 5);

    uart = fopen("uart0", "r+b");
    _ioctl(_fileno(uart), UART_SETSPEED, &baud);
        
    fputs_P(booting_P,uart); 
  
    fputs_P(conf_eth0_P,uart);
    if (NutDhcpIfConfig("eth0", 0, 60000)) {
        fputs_P(initial_boot_P,uart);
        if (NutDhcpIfConfig("eth0", mac, 60000)) {
            u_long ip_addr = inet_addr(MY_IP);
            u_long ip_mask = inet_addr(MY_MASK);
            fputs_P(no_dhcp_P,uart);
            NutNetIfConfig("eth0", mac, ip_addr, ip_mask);
        }
    }
    fputs_P(listen_to_P,uart);
    fprintf(uart,"%s\r\n", inet_ntoa(confnet.cdn_ip_addr));
 
    init_dio(uart);

    LoadPW();
    
    NutThreadCreate("xmit", Receiver, uart, 512);
  
   for (;;) {
        if ((sock = NutTcpCreateSocket()) != 0) {
            if (NutTcpAccept(sock, TCPPORT) == 0) {
                if ((stream = _fdopen((int) sock, "r+b")) != 0) {
                    ProcessRequests(stream);
                    fclose(stream);
                    NutTcpCloseSocket(sock);
                } 
            } 
        }
    }
}
    



More information about the En-Nut-Discussion mailing list