Skip to content

The Olduino Server Code

February 25, 2014

Like all my best work, I cribbed this. In this case I got it from http://www.ermicro.com/blog/?p=1773 which is an excellent treatise on using the wiznet w5100 chip with a microcontroller. It’s based on an AVR but was easy to adapt because it’s very clearly written. I stripped it down to bare bones, sacrificing flexibility for simplicity, and simplified the html form again for brevity.

The first code block below is the body of the main procedure. It initializes the wiznet chip then settles into a loop polling the status of the connection on socket 0(of 4) which is the only one I use. The status starts out as SOCK_CLOSED which drives us to initialize it. It becomes SOCK_LISTEN which we don’t care about until it changes to SOCK_ESTABLISHED which means there is incoming data. The remaining case are situations where the easiset thing is to restart the session so we do.

    W5100_Init(); //initialize the wiznet chip
	while(1){  // Loop forever
		socket0status=SPI_Read(S0_SR);
		//printf("s0s=%x ",socket0status);
		switch (socket0status){
			case SOCK_CLOSED: //initial condition
				socket0_init();	//initialize socket 0
				break;
			case SOCK_ESTABLISHED: //someone wants to talk to the server
				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:
				close0();
				break;
		}
		delay(100);
	}

The next code block handles a browser request. It starts by getting rsize – the amount of data that’s been received. This will be a surprisingly large figure like 366 bytes. Because most of it is poop and my transmission is slow, I only grab the first 12 bytes. The string will start with either GET or POST. A GET will come first when someone first enters the IP address or refreshes the window – that causes us to send the form. A POST request means someone has clicked the “toggle led” button on the web page so we call “handlepost()”. The “GET /favicon” request is something browsers do for every new web page you visit. It’s just an annoyance here so we send a “not found” type error which the browser accepts and ignores.

Having acted on the request, we call flush() to skip over the rest of the incoming data and free up the buffer.

void handlesession(){	//handle a session once it's established
	unsigned int rsize,strncmpval;
	rsize=recv_size();
	if (rsize>0){
		if (recv0(buf,min(12,rsize))>0){
			strncmpval=strncmp((char *)buf,"POST /",6);
  			if (strncmp((char *)buf,"POST /",6)==0){
  				handlepost(); //handle a button press
			}
			else if (strncmp((char *)buf,"GET /favicon",12)==0){
  				sendnak(); //no favicon here
			}
  			else if (strncmp((char *)buf,"GET /",5)>=0){
 				sendform(); //send the form
			}
		}
	}
  	if (rsize>0) flush(rsize);	//get rid of the received data
	disconnect0();	//in any case, we're done here
}

The web page that gets sent is about as simple as you can make it and still do anything. You can see the HTML below. The only thing that changes from page to page is the count of pages served, the last ip address that toggled the led, and the led status. Besides that you see the header and trailer and two “form” sections. Normally these sections would have more to them such as input fields or multiple choice buttons but by trimming them down this much we can just look at whether it’s a POST or a GET request and either toggle the led or just send status. Since the initial request from a new browser session is a GET, it’s identical to requesting the led status.

<html><body><span style="color:#0000A0">
<h1><center>Olduino 1802 Web Server V5.2</center></h1>

Pages Served: 2
<p>Last command from: 169.254.6.245
<p>LED is ON

<p><form method="POST">
<input type="submit" value="Toggle LED">
</form>

<p><form method="GET">
<input type="submit" value="LED Status">
</form>

</body></html>

The code block below sends the web page. You can see it counting the page hits then calling the send0s routine to send the static text and the variable items. In the static items at the top of the routine you see some extra HTTP gobbledygook and strings are terminated with \r and \n for carriage-return and newline codes.

void sendform(){
	int sendrc;
	static char hdr[]="HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n"
						"<html><body><span style=\"color:#0000A0\">\r\n"
						"<h1><center>Olduino 1802 Web Server V4.2</center></h1>\r\n";

	static char postform[]="<p><form method=\"POST\">\r\n"
						"<input type=\"submit\" value=\"Toggle LED\">\r\n"
						"</form>";
	static char getform[]="<p><form method=\"GET\">\r\n"
						"<input type=\"submit\" value=\"LED Status\">\r\n"
						"</form>";
	static char trlr[]="</body></html>\r\n\r\n";
	pagehits+=1;
	sendrc=send0s(hdr); 	// Now Send the HTTP Response first part
	send0s("Pages Served: "); send0s(itoa(pagehits,strbuf)); send0s("<p>");
	if (cmdip[0]!=0)
		sendip();
	sendrc=send0s("LED is ");
	if (ledmode==1)
		send0s("ON\r\n");
	else
		send0s("OFF\r\n");
	sendrc=send0s(postform); 	// Now Send the "POST" form
	sendrc=send0s(getform); 	// Now Send the "GET" form
	sendrc=send0s(trlr); 	// Now Send the rest of the page
}

The final code block below handles a post request. It switches the state of Q and records the requester’s IP address. It finally calls sendform() to update the page.

void handlepost(){
	if (ledmode==1){
		ledmode=0;
		asm("	req\n");
	} else {
		ledmode=1;
		asm("	seq\n");
	}
	cmdip[0]=SPI_Read(S0_DIPR + 0);cmdip[1]=SPI_Read(S0_DIPR + 1);cmdip[2]=SPI_Read(S0_DIPR + 2);cmdip[3]=SPI_Read(S0_DIPR + 3);
	sendform();
}

I had been thinking of adding a bunch of features to the page but I may just leave it as a simple example.

The full code is available on the LCC1802 downloads page at https://sites.google.com/site/lcc1802/downloads

Oh, for bonus info, here’s what gets sent by a browser starting a session. It’s just chock full of junk that would be of use to a more sophisticated server but is just noise to us here

GET /? HTTP/1.1
Host: 169.254.180.2
Connection: keep-alive
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.117 Safari/537.36
Referer: http://169.254.180.2/?
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Advertisements

From → web server

Leave a Comment

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: