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

#include <stdio.h>
#include <string.h>
#include "net.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)

#define RTC	0x9e				// RTC IIC bus address

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

/*
 * The html page to be sent. "XXXXXX" is a
 * place holder for the temperature value.
 */
static char page[] =
	"<html>"
	"<head>"
	"<meta http-equiv=Refresh content=30>"		// auto
	"<meta http-equiv=Pragma content=no-cache>"	//  reload
	"<title>NET2106 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>NET2106 WEB-Server</font></h1>"
	"<h4><font color=white>Test page...</font></h4>"
	"<h3>Board temperature:</h3>"
	"<p><font size=7 color=yellow>XXXXXX&deg;C</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
};

/*
 * Read the RTC temperature sensor.
 *
 * Return temperature string in the
 * form "+/-ddd.d".
 */
static char *
getts(void)
{
	static char s[7];			// temp. string
	signed char t[2];			// temp. (integral/fraction val)

	if (iic_start(RTC)
	 || iic_write("\xee", 1)		// start convert T cmd
	 || iic_start(RTC)
	 || iic_write("\xaa", 1)		// read temperature cmd
	 || iic_start(RTC|1)
	 || iic_read(t, 2)) puts("Reading temperature failed!"), abort();

	/*
	 * If the fraction value is non-zero the temperature is
	 * 0.5 degree higher. This means, the integral value is
	 * one degree higher, in case it is negative.
	 */
	sprintf(s, "%+4d.%d", t[1] && *t < 0? *t+1: *t, t[1]? 5: 0);
	return s;
}

/*
 * 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)
{
	char *p = strstr(page, "XXXXX");	// find temperature place holder

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

	printf("\n"
	       "NET2106 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_SMR ), net_rb(NET_SMR +1), net_rb(NET_SMR +2), net_rb(NET_SMR +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_C0_SPR));

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

		printf("Connected (%3d.%3d.%3d.%3d), sending ",
			net_rb(NET_C0_DIR  ),
			net_rb(NET_C0_DIR+1),
			net_rb(NET_C0_DIR+2),
			net_rb(NET_C0_DIR+3)
		);
		memset(req, 0, sizeof(req));
		net_read(req, sizeof(req)-1);
		if (strstr(req, "GET / HTTP")) {
			puts("page...");
			if (p) strncpy(p, getts(), 6);	// copy temperature 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();
	}
}

