📄 webserver.c
字号:
/***************************************************************************
;
; 2002 Altera Corporation. All rights reserved. Altera products are protected
; under numerous U.S. and foreign patents, maskwork rights, copyrights and other
; intellectual property laws. This reference design file, and your use thereof,
; is subject to and governed by the terms and conditions of the applicable
; Altera Reference Design License Agreement (found at www.altera.com). By using
; this reference design file, you indicate your acceptance of such terms and
; conditions between you and Altera Corporation. In the event that you do not
; agree with such terms and conditions, you may not use the reference design file
; and please promptly destroy any copies you have made. This reference design
; file being provided on an "as-is" basis and as an accommodation and therefore
; all warranties, representations or guarantees of any kind (whether express,
; implied or statutory) including, without limitation, warranties of
; merchantability, non-infringement, or fitness for a particular purpose, are
; specifically disclaimed. By making this reference design file available, Altera
; expressly does not recommend, suggest or require that this reference design file
; be used in combination with any other product not provided by Altera.
;
;***************************************************************************
;
; Filename: webserver.c
;
;***************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "wosfs.h"
#include "plugs.h"
#include "nios_compatibility.h"
#include "init_ether_and_plugs.h"
#include "stripe.h"
#include "serial.h"
#include "webserver.h"
http_message_request_type http_request;
http_message_response_type http_response;
int index;
extern unsigned char hex_data[4000000];
extern unsigned char bin_data[4000000];
extern unsigned char cond_bin_array[4000000];
extern ip_control_struct tcp_control;
//char html_response[1000];
// +---------------------------------
// | prototypes
static void r_get_cgi_param(char *url_and_args,char *parameter, char *value_out);
void cond_bin_data(int length);
static int r_get_html_from_wosfs(char *url,char *html_out,int *html_length_out);
static int r_get_html_404(char *url,char *html_out);
static int r_substitute_string(char *fmt,char *s);
static int r_get_html_dynamically(char *url,char *url_and_args,char *html_out);
int r_hex_char_to_value(char *c, int size_of_string);
void get_method(int plug_handle);
void post_method(int plug_handle);
void convert_hex_data_to_bin(void);
int get_content_length(void);
static unsigned char *get_next_line_in_http_request(void);
void send_http_response(int plug_handle);
unsigned char *get_record(int record_index);
void program_flash(int length);
void write_flash(unsigned short *address, short int value);
// +-------------------------------------------
// | r_handle_http_request(plug_handle, http_request, http_request_length)
// |
// | Actually, we just assume that the message
// | is, in fact, an HTTP request. An HTTP
// | request is of the form:
// |
// | GET <url>[ <http-version>](CR)(LF)
// |
// | It may also continue with more information
// | on subsequent lines, each of the form:
// |
// | <variable>: <value>
// |
// | And eventually ends with two CR-LF's.
// | But we ignore everything past the first
// | line here.
// |
// | To reply, we send a status line and
// | a content-type, followed by to CRLF's and the HTML.
// |
// | HTTP/1.1 200 OK
// | Content-type: <content-type>
// |
// | <HTML>
// |
// | The content type is either "text/html" or "image/gif".
// | We presume that if the content comes from WOSFS,
// | and the last letter of the filename is 'f', then it's
// | a GIF image.
// |
void r_handle_http_request(int plug_handle,unsigned char *message, int message_length)
{
char get[4];
char post[5];
volatile unsigned int *watch_dog = (volatile unsigned int *)EXC_WATCHDOG00_BASE;
volatile unsigned int *watch_dog_count = (volatile unsigned int *)EXC_WATCHDOG00_BASE + 1;
strcpy(post, "POST");
strcpy(get, "GET");
++tcp_control.inquiry_number;
http_request.http_message_request_head = message; //load the address of the begining of the message
http_request.http_message_line_index = message;
http_request.http_message_index = message; //initialize the index to the beginning of the request
http_request.http_message_length = message_length; //Add the payload length to the structure
http_request.http_message_end = message + message_length; //Load the message length to the structure
http_request.method_size = 0;
// |
// | Get the method name by looking for the first ' '
// |
while(http_request.http_message_index < http_request.http_message_end
&& *http_request.http_message_index != ' ') // parse message until we get to the first space.
{
http_request.method[http_request.method_size++] = *http_request.http_message_index;
http_request.http_message_index++;
}
http_request.method[http_request.method_size++] = 0; // Terminate string
// |
// | Move forward in the request to the '/'
// |
while(http_request.http_message_index < http_request.http_message_end
&& *http_request.http_message_index++ != '/');
// |
// | Copy the URL and any CGI arguments into url_and_args.
// | look for the end of the URL and CGI parameters as a ' ' or crlf
// |
http_request.url_and_args_length = 0; //initialize the url_and_arg_length
while(http_request.http_message_index < http_request.http_message_end
&& *http_request.http_message_index > ' ') // | break on blank or ctrl char
{
http_request.url_and_args[http_request.url_and_args_length++] = *http_request.http_message_index++;
}
http_request.url_and_args[http_request.url_and_args_length] = 0; // | Terminate string
//|I have got all of the parameters for the request. Now start to process it
// |
// | Asking for the root of the server, "/", means
// | they want "index.html".
// |
if(http_request.url_and_args_length == 0) // empty url?
{
strcpy(http_request.url_and_args,"index.html");
http_request.url_and_args_length = strlen(http_request.url_and_args);
}
r_get_cgi_param(http_request.url_and_args,0,http_request.url); // null param = URL
if(http_request.url_and_args_length == 0) // empty url?
{
strcpy(http_request.url_and_args,"index.html");
http_request.url_and_args_length = strlen(http_request.url_and_args);
}
r_get_cgi_param(http_request.url_and_args,0,http_request.url); // null param = URL
if(!strcmp(http_request.method, get))
{
get_method(plug_handle);
r_start_listening();
}
else if(!strcmp(http_request.method, post))
{
post_method(plug_handle);
}
else //Just reset board if method is not get or post
{
printf("[handle_http_request]: Received an unsupported method\n");
printf("[handle_http_request]: Resetting board\n");
*watch_dog = (*watch_dog_count) + 10000; //reset device
}
}
unsigned char *get_record(int record_index)
{
if(record_index == 0) //look for the first line
{
index = 0;
while(!((hex_data[index] == ':') && (hex_data[index + 1] == '0')))
{
index++;
}
}
else
{
index++; //move to next char
while(hex_data[index] != ':')
{
index++;
}
}
return &hex_data[index];
}
int r_hex_char_to_value(char *c, int size_of_string)
{
int value;
int location = 0;
int newvalue = 0;
while(*c != '\0')
{
value = *c & 0x000f;
if(*c > '9')
value += 9;
newvalue = newvalue + (value * (pow(16,(size_of_string - location - 1)))) ;
c++;
location++;
}
return newvalue;
}
void write_flash(unsigned short *address, short int value)
{
short int check;
short int prog_done_mask = (1<<7);
*address = 0x0060; // Enter Unlock command (0x60)
*(address + (0x1F8000)) = 0x00D0; // Unlock the first block BA = 0x08 (0xD0 unlocks the flash)
*address = 0x0090; // Move to Read Status Mode
check = *(address+0x0002); //*********add a check for the lock status
*address = 0x0020; //Enter Erase Mode
*(address + (0x1F8000)) = 0x00D0; //Enter Erase confirm commnad
*(address + 0x000) = 0x00D0; //Enter Erase confirm commnad
*address = 0x0070; //Switch to Read Status Mode
check = *address;
while ((check & prog_done_mask) == 0) {
check = *address;
}
*address = 0x0050;
*address = 0x00FF;
*address = 0x0060; // Enter Unlock command (0x60)
*(address + (0x1F8000)) = 0x00D0; // Unlock the first block BA = 0x08 (0xD0 unlocks the flash)
*address = 0x0090; // Move to Read Status Mode
check = *(address+0x0002); //*********add a check for the lock status
*address = 0x0040;
*(address + (0x1FFFFF)) = value; //Write Value to Flash
*address = 0x0070; //Switch to Read Status Mode
check = *address;
while ((check & prog_done_mask) == 0) //Check to see if programming is done
check = *address;
*address = 0x0050; //Clear Read Status Register
}
void program_flash(int length)
{
short int check;
short int end_of_para_block_mask = 0xFFF;
short int end_of_block_mask = 0x7FFF;
short int prog_done_mask = (1<<7);
short int lock_block_mask = 3;
short int erase_status_mask = (1<<5);
short int value_to_send;
int index = 0;
int i = 0;
unsigned char *EBI1_check = (unsigned char *)EXC_EBI_BLOCK1_BASE;
unsigned short *EBI1_write = (unsigned short *)EXC_EBI_BLOCK1_BASE;
volatile unsigned int *watch_dog = (volatile unsigned int *)EXC_WATCHDOG00_BASE;
volatile unsigned int *watch_dog_count = (volatile unsigned int *)EXC_WATCHDOG00_BASE + 1;
volatile unsigned short *EBI1 = (volatile unsigned short *)EXC_EBI_BLOCK1_BASE;
volatile unsigned short *EBI1_watch = (volatile unsigned short *)EXC_EBI_BLOCK1_BASE;
unsigned short *EBI1_magic = ( unsigned short *)EXC_EBI_BLOCK0_BASE;
printf("Starting flash programming\n");
while(index < (EXC_EBI_BLOCK1_SIZE)) //Erase and unlock flash
{
if(index < 0x10000)
{
if((index & end_of_para_block_mask) == 0x0000)
{
printf("Erasing Flash Block on EBI1 at address: 0x%X\r", (int)EBI1);
EBI1_watch = EBI1;
*EBI1_watch = 0x0060; //Unlock command
*EBI1_watch = 0x00D0; //Unlock the block
*EBI1_watch = 0x0090; //Enter read configuation status
check = *(EBI1_watch + 2); //Read the configuration status
while ((check & lock_block_mask) != 0) //Check lock status
{
check = *(EBI1_watch + 2);
}
*EBI1_watch = 0x0020; //Enter Erase Mode
*EBI1_watch = 0x00D0; //Enter Erase confirm commnad
*EBI1_watch = 0x0070; //Switch to Read Status Mode
check = *EBI1_watch;
while ((check & prog_done_mask) == 0) {
check = *EBI1_watch;
}
if((check & erase_status_mask)==1)
{
printf("Erase error at address %x\n", (int)EBI1_watch);
printf("Resetting board\n");
*watch_dog = (*watch_dog_count) + 10000; //reset device
}
*EBI1_watch = 0x0050;
*EBI1_watch = 0x00FF;
}
}
else
{
if((index & end_of_block_mask) == 0x0000)
{
printf("Erasing Flash Block on EBI1 at address: 0x%X\r", (int)EBI1);
EBI1_watch = EBI1;
*EBI1_watch = 0x0060; //Unlock command
*EBI1_watch = 0x00D0; //Unlock the block
*EBI1_watch = 0x0090; //Enter read configuation status
check = *(EBI1_watch + 2); //Read the configuration status
while ((check & lock_block_mask) != 0)
{
check = *(EBI1_watch + 2);
}
*EBI1_watch = 0x0020; //Enter Erase Mode
*EBI1_watch = 0x00D0; //Enter Erase confirm commnad
*EBI1_watch = 0x0070; //Switch to Read Status Mode
check = *EBI1_watch;
while ((check & prog_done_mask) == 0) {
check = *EBI1_watch;
}
if((check & erase_status_mask)==1)
{
printf("Erase error at address: 0x%x\n", (int)EBI1_watch);
printf("Resetting board\n");
*watch_dog = (*watch_dog_count) + 10000; //reset device
}
*EBI1_watch = 0x0050;
*EBI1_watch = 0x00FF;
}
}
EBI1++;
index = index + 2;
}
printf("\nWriting new image to flash on EBI1 located at address: 0x%X\n", EXC_EBI_BLOCK1_BASE);
index = 0; //reset index so it can be used for writing.
while(index <= length)
{
value_to_send = cond_bin_array[index + 1];
value_to_send = (value_to_send << 8);
value_to_send = value_to_send + cond_bin_array[index];
if((index & end_of_para_block_mask) == 0x0000) //just use this to print to the screen so the
{
printf("."); //user knows something is happening
}
*EBI1_write = 0x0040;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -