[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