/*
 * Copyright(C) Paul und Scherer (mct.de/mct.net)
 *
 * This example demonstrates how to...
 *
 *  ... use the ethernet module as simple
 *      http server (port #80).
 */

#include <stdio.h>
#include <string.h>
#include "net1.h"

#define SN	(255L<<24|255L<<16|255L<<8|192)	// choose subnet  mask
#define GW	(194L<<24| 64L<<16|159L<<8| 65)	//        gateway addr
#define IP	(194L<<24| 64L<<16|159L<<8| 79)	//        IP      addr
#define PN	80				//        port  number (http)

static char const head[] = "HTTP/1.1 200 OK\n\n";	// GET response header

/*
 * SPIMS (SPI Made Simple) chip selects
 */
#define CS0	0x10000				// P0.16
#define CS1	0x20000				// P0.17
#define CS2	0x40000				// P0.18
#define CS3	0x80000				// P0.19

/*
 * The html page to be sent. "XXXXX" is a
 * place holder for the page load count.
 */
static char page[] =
	"<html>"
	"<head>"
	"<meta http-equiv=Refresh content=30>"		// auto
	"<meta http-equiv=Pragma content=no-cache>"	//  reload
	"<title>SPImSnet1 WEB-Server</title>"
	"</head>"
	"<body bgcolor=red>"
	"<center>"
	"<p><font size=-1>This page is automagically reloaded every 30 seconds.</font></p>"
	"<h1><font color=white>SPImSnet1 WEB-Server</font></h1>"
	"<h4><font color=white>Test page...</font></h4>"
	"<h3>Page load count:</h3>"
	"<p><font size=7 color=yellow>XXXXX </font></p>"
	"<p><a href=http://www.mct.de  target=_blank>mct.de </a><br>"
	"   <a href=http://www.mct.net target=_blank>mct.net</a></p>"
	"</center>"
	"</body>"
	"</html>";

static char const favicon[] =
{
 0x00,0x00,0x01,0x00,0x01,0x00,0x10,0x10,0x00,0x00,0x01,0x00,0x18,0x00,0x68,0x03,
 0x00,0x00,0x16,0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x20,0x00,
 0x00,0x00,0x01,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc1,0xc3,
 0xff,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,
 0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0xff,0xff,0x01,0x01,0xf9,0x00,0x00,0xfe,0x00,
 0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0xc1,0xc3,
 0xff,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,
 0x00,0x00,0xfe,0x00,0x01,0xfd,0x00,0xff,0xff,0x02,0x02,0xee,0x00,0x00,0xfe,0x00,
 0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0xc1,0xc3,
 0xff,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,
 0x00,0x00,0xfe,0x00,0x01,0xfd,0x00,0xff,0xff,0x02,0x02,0xee,0x00,0x00,0xfe,0x00,
 0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0xc1,0xc3,
 0xff,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,
 0x00,0x00,0xfe,0x00,0x01,0xfd,0x00,0xff,0xff,0x02,0x02,0xee,0x00,0x00,0xfe,0x00,
 0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0xc1,0xc3,
 0xff,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,
 0x00,0x00,0xfe,0x00,0x00,0xfe,0x03,0x06,0xe4,0x00,0x01,0xfd,0x00,0x00,0xfe,0x00,
 0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0xc1,0xc3,
 0xff,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,
 0x00,0x01,0xfd,0x26,0xfa,0xfb,0x7f,0x7f,0x7f,0x7e,0xa6,0xa5,0x01,0x02,0xfe,0x00,
 0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0xc1,0xc3,
 0xff,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,
 0x7e,0xef,0xec,0x00,0xff,0xff,0x00,0xff,0xff,0x00,0xff,0xff,0x85,0x85,0x85,0x00,
 0x00,0xf8,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0xc1,0xc3,
 0xff,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,
 0x96,0x94,0x94,0x00,0xff,0xff,0x00,0xff,0xff,0x00,0xff,0xff,0x87,0x87,0x87,0x02,
 0x04,0xfd,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0xc1,0xc3,
 0xff,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,
 0x9e,0xa3,0xa6,0x00,0xff,0xff,0x00,0xff,0xff,0x00,0xff,0xff,0x8e,0x8d,0x8f,0x00,
 0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0xc1,0xc3,
 0xff,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,
 0x02,0x00,0xfe,0x90,0x92,0x92,0x7b,0x7b,0x7b,0xa9,0xac,0xaa,0x00,0x00,0xf8,0x00,
 0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0xc1,0xc3,
 0xff,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,
 0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,
 0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0xc1,0xc3,
 0xff,0x00,0x00,0xfe,0x00,0x01,0xfd,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,
 0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x01,0xfd,0x02,0x00,0xfd,0x00,0x00,0xfe,0x00,
 0x00,0xfe,0x00,0x00,0xfe,0x00,0x01,0xfd,0x00,0x00,0xfe,0x00,0x00,0xfe,0xc1,0xc3,
 0xff,0x00,0x00,0xfe,0x00,0xff,0xff,0x10,0x11,0xcd,0x00,0xff,0xff,0x00,0xff,0xff,
 0x04,0x22,0xc1,0x11,0xfc,0xfe,0x00,0xff,0xff,0x03,0x05,0xf7,0x00,0xff,0xff,0x02,
 0x02,0xfa,0x00,0x01,0xfd,0x00,0xff,0xff,0x03,0x01,0xfe,0x00,0x00,0xfe,0xc1,0xc3,
 0xff,0x00,0x00,0xfe,0x00,0xff,0xff,0x00,0xff,0xff,0x00,0xff,0xff,0x01,0xff,0xff,
 0x04,0x23,0xc0,0x00,0xff,0xff,0xaa,0xdb,0xff,0x00,0x00,0xfe,0x00,0x02,0xfb,0x00,
 0x01,0xfd,0x00,0x01,0xfd,0x00,0xff,0xff,0x03,0x01,0xfe,0x00,0x00,0xfe,0xc1,0xc3,
 0xff,0x00,0x00,0xfe,0x00,0xff,0xff,0x00,0xff,0xff,0x05,0x05,0xeb,0x00,0xff,0xff,
 0x04,0x23,0xc0,0x08,0x09,0xe3,0x00,0xff,0xff,0x00,0xff,0xff,0x01,0xff,0xff,0x00,
 0x00,0xf9,0x00,0xff,0xff,0x00,0xff,0xff,0x00,0xff,0xff,0x02,0x01,0xfb,0xc1,0xc3,
 0xff,0x00,0x00,0xfe,0x01,0x01,0xff,0x01,0x01,0xff,0x02,0x00,0xfe,0x01,0x01,0xff,
 0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,
 0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,
 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};

/*
 * The SPI is setup as master (CPOL =0, CPHA =0).
 *
 * Note: A pullup is needed for slave select (=P0.7), when
 * in master mode!
 */
static void
spi_init(void)
{
	Intern_pinsel0 |= 0x5500;		// enable SPI pins
	Intern_spcr     = 0x20;			// MSTR
	Intern_spccr    = 8;			// SCK =pclk/8
}

/*
 * The ethernet module channel 0 is initialized in TCP server mode.
 *
 * On connect, "HTTP" and "favicon" requests are serviced. For HTTP
 * requests, the page load count is copied into the html page prior
 * to sending the page. After sending data, the channel gets closed
 * until the next connection is made.
 */
int
main(void)
{
	short loaded = 0;
	char *p = strstr(page, "XXXXX");	// find load count place holder

	/*
	 * De-select all SPImS devices.
	 */
	Intern_ioset  = CS0|CS1|CS2|CS3;
	Intern_iodir |= CS0|CS1|CS2|CS3;

	spi_init();				// initialize SPI
	net_init(SN, GW, IP);			//            NET module

	printf("\n"
	       "NET1 TCP server\n"
	       "===============\n\n"
	       "     Subnet mask : %3d.%3d.%3d.%3d\n"
	       " Gateway address : %3d.%3d.%3d.%3d\n"
	       "      IP address : %3d.%3d.%3d.%3d\n",
		net_rb(NET_SUBR), net_rb(NET_SUBR+1), net_rb(NET_SUBR+2), net_rb(NET_SUBR+3),
		net_rb(NET_GAR ), net_rb(NET_GAR +1), net_rb(NET_GAR +2), net_rb(NET_GAR +3),
		net_rb(NET_SIPR), net_rb(NET_SIPR+1), net_rb(NET_SIPR+2), net_rb(NET_SIPR+3)
	);

	while (1) {
		static char req[15];		// request buffer

		net_open(PN, 0);		// initialize socket (listen)

		printf("\nDisconnected, waiting for connection (port #%d)...\n", net_rw(NET_S0_PORT));

		while (net_rb(NET_S0_SR) != NET_SE) ;	// wait for sock_established

		printf("Connected (%3d.%3d.%3d.%3d), sending ",
			net_rb(NET_S0_DIPR  ),
			net_rb(NET_S0_DIPR+1),
			net_rb(NET_S0_DIPR+2),
			net_rb(NET_S0_DIPR+3)
		);
		memset(req, 0, sizeof(req));
		net_read(req, sizeof(req)-1);
		if (strstr(req, "GET / HTTP")) {
			puts("page...");
			if (p) sprintf(p, "%5d", ++loaded), p[5] = ' ';	// copy load count into page
			net_write(head, sizeof(head)-1);
			net_write(page, sizeof(page)-1);
		} else
		if (strstr(req, "GET /favicon")) {
			puts("favicon...");
			net_write(head	 , sizeof(head)-1 );
			net_write(favicon, sizeof(favicon));
		} else	puts("nothing (unknown request)");
		net_close();
	}
}

