Skip to content

A Bad Telnet Approach

February 6, 2016

16-02-06 onegame

So, if all I wanted to do was play “Doughnuts” over Telnet I could declare victory now.  I swallowed my pride and implemented a blocking tgetline() that throws away control characters and returns only when it sees an end of line.  I embedded that in a modified version of the web server code and it “works”.  It would only play a single game and has other functional limits but the worst problem is that it could host only a single user at a time and would refuse other connections.  To correct that I need to support multiple sockets and sort of turn the code on its head so the input is being read at the top level and passed down rather than inside the game itself. For now, though, I think I’ll go sit in the sun and read a book.

The first set of code has: tgetcraw which gets a single character from the wiznet chip and removes it from the buffer; tgetchar which filters out initialization sequences; and tgetline which assembles a line in a buffer passed and returns it when the \r\n sequence signals the end of the line.

unsigned char tgetcraw(){//get a raw character from telnet
	unsigned int rsize;
	while(wizGetCtl16(SnRX_RSR)==0);
	recv0(buf,1);flush(1);
	return buf[0];
}
unsigned char tgetchar(){//get a character from telnet
	unsigned char craw;
	craw=tgetcraw();
	while (craw==255){//negotiation sequence
		craw=tgetcraw();craw=tgetcraw();
		craw=tgetcraw();
	}
	return craw;
}
unsigned int tgetline(unsigned char * linebuf, unsigned int maxlen){
	unsigned char c,tgotlen=0;
	c=tgetchar();
	while(c!='\r' && c!='\n'){
		*linebuf=c;
		if (tgotlen<maxlen){
			linebuf++; tgotlen++;
		}
		c=tgetchar();
	}
	if (c='\r'){c=tgetchar();} //swallow the lf of a cr,lf pair
	*linebuf=0; //terminate linebuf
	return tgotlen;
}

/*****************************************************************************
//  File Name    : w5500tdonuts.c
//  Version      : 1
//  Description  : Simple Telnet Server With Wiznet w5500
//  Author       : Bill Rowe
//  Target       : Olduino
//  Compiler     : LCC1802
//  Created	 : Feb 6, 2016
*****************************************************************************/
#define nofloats
#include <nstdlib.h> //for printf etc.
#include <cpu1802spd4port7.h> //defines processor type, speed, and host port
#include <olduino.h> //for digitalRead, digitalWrite, delay
#include <hspi2.h> //hardware spi header
//end of olduino/1802 specific declares
#include "w5500data.h"  //wiznet definitions
#include "w5500code.h"  //wiznet code definitions
union IPaddr thisip={182}; //the ip that a form/request came from
#define MAX_BUF 512
unsigned char buf[MAX_BUF];			//memory buffer for incoming & outgoing data
	static unsigned char Inst1[]=
		"I AM THINKING OF A 3 DIGIT NUMBER.\n\rTRY TO GUESS " //50
		"MY NUMBER AND I WILL GIVE YOU CLUES AS FOLLOWS:\n\r";
	static unsigned char Inst2[]=
		"...PICO - ONE DIGIT IS IN THE WRONG PLACE\n\r"
		"...FERMI - ONE DIGIT IS IN THE CORRECT PLACE\n\r"
		"...DOUGHNUTS - NO DIGIT IS CORRECT\n\r";
unsigned char secret[4]="145";
unsigned char guess [4]={0};
unsigned int pages=0; games=0; sessions=0,turns=0;
char pnbuf[8];
unsigned int tbrnd(){//random numbers ala tiny basic R:=R*2345+6789
	static unsigned int R=1;
	R=R*58653+13849;//R=R*2345+6789;
	//printf("%d\n",R);
	return R;
}
void setsecret(){//set the global secret to a 3 digit random number
	int i=0,d1=0,d2,d3;
	while(d1==0){
		d1=tbrnd()%10;
	}
	d2=tbrnd()%10;
	while(d1==d2){
		d2=tbrnd()%10;
	}
	d3=tbrnd()%10;
	while(d3==d1||d3==d2){
		d3=tbrnd()%10;
	}
	secret[0]=d1+0x30;secret[1]=d2+0x30;secret[2]=d3+0x30;secret[3]=0;
	printf("secret=%s\n",secret);
}
void bagelsinit(){
	int sendrc;
	games++;
	pages++;
	setsecret();
	printf("IP: %d.%d.%d.%d,slot %d,secret %s\n",
		thisip.c[0],thisip.c[1],thisip.c[2],thisip.c[3],0,secret);
}
void phexblk(unsigned char * buf,unsigned int len){
	int i;
	for (i=0;i<len;i++){
	printf("%cx",buf[i]);
	}
}
unsigned char tgetcraw(){//get a raw character from telnet
	unsigned int rsize;
	while(wizGetCtl16(SnRX_RSR)==0);
	//rsize=wizGetCtl16(SnRX_RSR); //get the size of the received data
	//printf("rawsize=%d ",rsize);
	recv0(buf,1);flush(1);
	//printf(" rawchar=%cx\n",rsize,buf[0]);
	return buf[0];
}
unsigned char tgetchar(){//get a character from telnet
	unsigned char craw;
	craw=tgetcraw();
	while (craw==255){//negotiation sequence
		craw=tgetcraw();craw=tgetcraw();
		craw=tgetcraw();
	}
	return craw;
}
unsigned int tgetline(unsigned char * linebuf, unsigned int maxlen){
	unsigned char c,tgotlen=0;
	c=tgetchar();
	while(c!='\r' && c!='\n'){
		*linebuf=c;
		if (tgotlen<maxlen){
			linebuf++; tgotlen++;
		}
		c=tgetchar();
	}
	if (c='\r'){c=tgetchar();} //swallow the lf of a cr,lf pair
	*linebuf=0; //terminate linebuf
	return tgotlen;
}
void sendresp(int pico, int fermi){
	unsigned int i;
	pages++;
	sendlit("  I say ");
	if (fermi==3){
		sendlit("YOU GOT IT!\r\n");
	} else {//once we're here we're going to send the guess form
		if (pico<0){//flag for duplicate digits
			sendconst("Oh, maybe I didn't tell you.  No two digits are the same.\r\n");
		} else if ((pico+fermi)==0){
			sendlit("Doughnuts!");
		} else{
			for(i=0;i<pico;i++) sendlit("Pico ");
			for(i=0;i<fermi;i++) sendlit("Fermi ");
		}
		sendlit("\r\n");
		sendconst("Try Again\r\n:"); 	// ask for another guess
	}
}
void bagelsturn(unsigned char guess[]){
	int i, /*ipslot,*/ pico=0, fermi=0;
	turns++; //count the turn
	for (i=0;i<3;i++){
		if (guess[i]==secret[i]){
			fermi++;
		}
	}
	if (guess[0]==secret[1]||guess[0]==secret[2]){pico++;}
	if (guess[1]==secret[0]||guess[1]==secret[2]){pico++;}
	if (guess[2]==secret[0]||guess[2]==secret[1]){pico++;}
	if (guess[0]==guess[1]||guess[0]==guess[2]||guess[1]==guess[2]||strlen((char *)guess)!=3){pico=-1;}
	sendresp(pico, fermi);
}

void handlesession(){
	unsigned char line[32]; unsigned int linelen;
	bagelsinit();
	sendconst(Inst1); sendconst(Inst2);
	linelen=tgetline(line,32);
	while((linelen<4)||strcmp("quit",line)!=0){
		bagelsturn(line);
		linelen=tgetline(line,32);
	}
	sendconst("I Say Byebye\r\n ");
	wizCmd(CR_DISCON);// Disconnect the connection- we're done here
}

void main(void){
	unsigned char socket0status,connectstatus=0,listening=0,prevstat=0xff;
    unsigned char ip_addr[] = {169,254,180,2};
	delay(500);
    wiz_Init(ip_addr); //initialize the wiznet chip
	while(1){  // Loop forever
		socket0status=wizGetCtl8(SnSR); //socket 0 status
		if (socket0status!=prevstat){
			printf("s0 stat change to %X\n\r",socket0status);
			prevstat=socket0status;
		}
		switch (socket0status){
			case SOCK_CLOSED: //initial condition
				socket0_init();	//initialize socket 0
				break;
			case SOCK_LISTEN:
				listening=1;
				break;
			case SOCK_ESTABLISHED: //someone wants to talk to the server
				if(connectstatus==0){
					connectstatus=1;
					thisip.l=getip();
					printf("Hello to: %d.%d.%d.%d\n",
							thisip.c[0],thisip.c[1],thisip.c[2],thisip.c[3]);
					sendconst("Oh Hello!!\n\r");
				}
				handlesession();
				break;
			//following are cases where we have to reset and reopen the socket
			case SOCK_FIN_WAIT: case SOCK_CLOSING: case SOCK_TIME_WAIT:
			case SOCK_CLOSE_WAIT: case SOCK_LAST_ACK:
				wizCmd(CR_CLOSE);
				break;
		}
		delay(100);
	}
}
#include <olduino.c>
#include <nstdlib.c>
#include <hspi2.c>
#include "w5500code.c"

 

 

Advertisements
One Comment

Trackbacks & Pingbacks

  1. Telenet Server on the Z80 | olduino

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: