#include "stdio.h"
#include
#include "rom400_init.h"
#include "rom400_sock.h"
#include "rom400_sched.h"
/*
* This program will maintain a couple files. One file will
* contain the current time, along with the last time we got
* the time from the time server. Another file will maintain
* some statistics, and still another file will contain the main
* index file, linking to the others.
*
*/
//
// Some defines for the program run.
//
#define RAM_START 0x14000
#define RAM_END 0x5FFFF
#define FS_START 0x60000
#define FS_BLOCKS 512 // 2 banks worth of file system
// Static IP Address (used if you are selecting a static IP)
#define STATIC_IP_MSB 180
#define STATIC_IP_2 0
#define STATIC_IP_3 54
#define STATIC_IP_LSB 91
// Static Subnet Mask (used if you are selecting a static IP)
#define STATIC_SUBNETMASK_MSB 255
#define STATIC_SUBNETMASK_2 255
#define STATIC_SUBNETMASK_3 0
#define STATIC_SUBNETMASK_LSB 0
#define STATIC_IPV4_PREFIX 16
// Static Gateway (used if you are selecting a static IP)
#define STATIC_GATEWAY_MSB 180
#define STATIC_GATEWAY_2 0
#define STATIC_GATEWAY_3 110
#define STATIC_GATEWAY_LSB 24
#define HTTP_INVALID_REQUEST 0
#define HTTP_FILENOTFOUND 1
#define HTTP_FILEERROR 2
char last_time_reading[200];
unsigned long last_reading_seconds;
unsigned long request_count;
void sendTimeFile(unsigned int handle);
void http_fail(unsigned int, unsigned int);
void time_server_start();
unsigned int http_server_start();
void handleRequest(unsigned int);
unsigned long getTimeSeconds();
void downloadTime();
unsigned char xdata config[56];
unsigned int initialize_network()
{
unsigned int i;
for (i=0;i<56;i++)
config[i] = 0;
//set the ip address
config[12] = STATIC_IP_MSB;
config[13] = STATIC_IP_2;
config[14] = STATIC_IP_3;
config[15] = STATIC_IP_LSB;
//set the subnet mask
config[16] = STATIC_SUBNETMASK_MSB;
config[17] = STATIC_SUBNETMASK_2;
config[18] = STATIC_SUBNETMASK_3;
config[19] = STATIC_SUBNETMASK_LSB;
//set the iP4 prefix
config[20] = STATIC_IPV4_PREFIX;
//set the gateway
config[33] = STATIC_GATEWAY_MSB;
config[34] = STATIC_GATEWAY_2;
config[35] = STATIC_GATEWAY_3;
config[36] = STATIC_GATEWAY_LSB;
return setnetworkparams(config);
}
void network_config()
{
unsigned char result;
unsigned int i;
for (i=0;i<56;i++)
config[i] = 0;
result = getnetworkparams(config);
printf("Network params result: %d\r\n", result);
printf("IP : %bu %bu %bu %bu\r\n", config[12], config[13], config[14], config[15]);
printf("Subnet: %bu %bu %bu %bu\r\n", config[16], config[17], config[18], config[19]);
printf("Prefix: %bu\r\n", config[20]);
printf("Gate : %bu %bu %bu %bu\r\n", config[33], config[34], config[35], config[36]);
}
void initialize_filesystem()
{
// it'd be nice for the filesystem to stick around between
// reboots, so I can keep track of the number of reboots,
// and activity since first birthday
FILE* file;
void* start = (void*)FS_START;
int x = finit(FOPEN_MAX, FS_BLOCKS, start);
printf("Result of FS init: %d \r\n", x);
// file = fopen("index.html", "w");
// fwrite(INDEX_FILE_CONTENTS, 1, strlen(INDEX_FILE_CONTENTS), file);
// lets get the files we want off a TFTP server
}
void main()
{
unsigned int temp;
char buffer[40];
request_count = 0;
printf("DS80C400 Timer Server Demonstration\r\n");
rom_init(RAM_START, RAM_END);
temp = initialize_network();
if (temp==0)
printf("Network parameters succesfully set.\r\n");
else
printf("Network parameters could not be set.\r\n");
network_config();
initialize_filesystem();
// start the time server
time_server_start();
// start the HTTP server
temp = http_server_start();
sprintf(buffer, "Process ID of HTTP server: %d\r\n", temp);
printf(buffer);
while(1)
{
// sleep for about a minute
task_sleep(0, 0, 60000);
downloadTime();
}
}
void time_server_start()
{
sprintf(last_time_reading, "No time reading has been taken yet.");
downloadTime();
}
unsigned int http_server_start()
{
int i, temp;
unsigned int socket_handle;
unsigned int new_socket_handle;
struct sockaddr address;
struct sockaddr local;
// spawn off a new process. The child will remain here and listen for connections.
unsigned int result;
EnterCritSection();
result = task_fork(NORM_PRIORITY, ROM_SAVESIZE);
if (result==0xFFFF)
{
LeaveCritSection();
printf("Attempt to start HTTP server failed\r\n");
return 0;
}
//else result is 0 for the child process, else it is the child PID
if (result==0)
{
// this is the child. Wait for a connection on port 80.
printf("\r\nCreating a new TCP connection for listening...");
socket_handle = socket(0, SOCKET_TYPE_STREAM, 0);
printf("Result of socket creation: %u\r\n", socket_handle);
for (i=0;i<18;i++)
{
local.sin_addr[i] = 0;
address.sin_addr[i] = 0;
}
local.sin_port = 80;
temp = bind(socket_handle, &local, sizeof(local));
printf("Result of bind to port 80: %x\r\n", temp);
temp = listen(socket_handle, 5);
printf("Result of listen : %x\r\n", temp);
printf("Ready to accept HTTP connections...\r\n");
while (1)
{
new_socket_handle = accept(socket_handle, &address, sizeof(address));
request_count++;
// This is just a simple example. A more complex server
// would spawn off a new thread/process to handle this request.
handleRequest(new_socket_handle);
closesocket(new_socket_handle);
}
}
else
{
// 'result' is the HTTP server's process ID
// Return to the main program
LeaveCritSection();
return result;
}
}
void handleRequest(unsigned int handle)
{
// Here we're looking for something like this:
// GET http://www.w3.org/pub/WWW/TheProject.html HTTP/1.1
// We'll ignore the first part of the URI and just look
// at the file name.
unsigned char buffer[101];
unsigned char request[20];
unsigned char filename[50];
unsigned char* fn;
unsigned char version[20];
int length, start;
unsigned int result = recv(handle, buffer, 100, 0);
printf("I am in handle Request\r\n");
printf("Result of recv %d \r\n", result);
if (result != 0xFFFF)
{
buffer[result] = 0;
printf("Result buffer: %s \r\n", buffer);
}
sscanf(buffer, "%s %s %s", request, filename, version);
printf("Request: %s\r\n", request);
printf("Filename: %s\r\n", filename);
printf("Version: %s\r\n", version);
// make sure this is a GET request. We don't know nuthin' else.
if (strncmp(request, "GET", 3) != 0)
{
http_fail(HTTP_INVALID_REQUEST, handle);
printf("...not a GET\r\n");
return;
}
// else let's get the filename
length = strlen(filename);
start = length;
while ((filename[start] != '/') && (start > -1))
start--;
start++;
// from start to length is the filename
fn = filename + start;
if (strcmp(fn, "time.html")==0)
{
sendTimeFile(handle);
printf("...filename is time.html\r\n");
return;
}
// request the filename from the file system, and write the bytes to the handle
printf("...looking for file...\r\n");
/*
file = fopen(fn, "r");
if (file==NULL)
{
http_fail(HTTP_FILENOTFOUND, handle);
return;
}
// else the file is valid
int amount = fread(file, buffer, 100);
while (amount > 0)
{
send(handle, buffer, amount, 0);
amount = fread(file, buffer, 100);
}
*/
}
static char* Response_404 = "HTTP/1.0 404 File Not Found\r\n";
static char* Response_405 = "HTTP/1.0 405 Invalid Request Method\r\n";
static char* Response_500 = "HTTP/1.0 500 Internal Server Error\r\n";
static char* CRLF = "\r\n";
static char* Message_404 = "The file requested could not be found. Stop snooping around. Please follow the links from index.html for a valid file.";
static char* Message_405 = "This server only supports the GET method. Please make a valid request or risk my wrath.";
static char* Message_500 = "Server had an error and could not fulfill this request. Please ask again when I feel better.";
void http_fail(unsigned int failcode, unsigned int handle)
{
// write out to handle the error text
switch(failcode)
{
case HTTP_FILENOTFOUND:
send(handle, Response_404, strlen(Response_404), 0);
send(handle, CRLF, strlen(CRLF), 0);
send(handle, Message_404, strlen(Message_404), 0);
return;
case HTTP_INVALID_REQUEST:
send(handle, Response_405, strlen(Response_405), 0);
send(handle, CRLF, strlen(CRLF), 0);
send(handle, Message_405, strlen(Message_405), 0);
return;
case HTTP_FILEERROR:
default:
send(handle, Response_500, strlen(Response_500), 0);
send(handle, CRLF, strlen(CRLF), 0);
send(handle, Message_500, strlen(Message_500), 0);
return;
}
}
unsigned long getTimeSeconds()
{
// this does a divide by 1024 on the milliseconds,
// close enough if we have 60 second time server updates
struct TIME t;
unsigned long temp;
GetTimeMillis(&t);
temp = (t.msb << 22);
temp = temp | (t.millis >> 10);
return temp;
return t.millis;
}
static char* RESPONSE_OK = "HTTP/1.0 200 Okily-Dokily\r\n";
static char* time_file_0 = "DS80C400 Time Server: Current Time The last result from the time server was: ";
static char* time_file_1 = ".
That reading was taken ";
static char* time_file_2 = " seconds ago.";
void sendTimeFile(unsigned int handle)
{
char buffer[50];
send(handle, RESPONSE_OK, strlen(RESPONSE_OK), 0);
send(handle, CRLF, strlen(CRLF), 0);
send(handle, time_file_0, strlen(time_file_0), 0);
send(handle, last_time_reading, strlen(last_time_reading), 0);
send(handle, time_file_1, strlen(time_file_1), 0);
sprintf(buffer, "%ld", getTimeSeconds() - last_reading_seconds);
send(handle, buffer, strlen(buffer), 0);
send(handle, time_file_2, strlen(time_file_2), 0);
}
void downloadTime()
{
// go contact the server
// 1 contact time.nst.gov and get the current time
// 2 update our records
// 3
last_reading_seconds = getTimeSeconds();
}